# Персональный блог Рената Алимбекова > Data Science, ML и Analytics Engineering ### Retrieval-Augmented Generation (RAG): Recent Research and Challenges In today's AI-driven world, Retrieval-Augmented Generation (RAG) is becoming an increasingly significant approach that combines the capabilities of information retrieval with the generative abilities of large language models (LLMs). This overcomes a number of limitations faced by traditional LLMs and provides more accurate and fact-based answers. What is RAG? RAG is not a single technology, but an entire umbrella of different components, designs, and domain-specific adaptations. A typical RAG system includes: A data ingestion component: where data is processed, embedded, and stored as context documents in a vector database A retrieval component: where context documents are retrieved and ranked for relevance to the query Query component: where the prompt with the query is combined with the search results and sent to the LLM Methodology for evaluating RAG systems Recent studies, including work by Simon and colleagues at the University of Leipzig, propose a methodological framework for evaluating RAG systems. Their approach includes: Independent variables: RAG architecture (embedding models, search methods, filters) and context sources Dependent variables: RAG performance metrics Evaluation: comparison with a baseline model (usually vanilla LLM) and use of benchmarks Improvements: error analysis and systematic improvements One of the most important aspects of developing a successful Retrieval-Augmented Generation (RAG) system is to evaluate it using objective metrics. Without proper performance measurement, it is impossible to determine if the system is actually working as intended and where improvements are needed. Four key metrics for evaluating RAG systems There are four key metrics that should be used to evaluate your RAG pipelines comprehensively: Information Accuracy (Faithfulness) The information accuracy metric measures how closely the generated response matches the context provided. Essentially, this metric indicates whether the model is making up facts not in the extracted documents. It is scored on a scale of 0 to 1 Higher values indicate better factual accuracy A low score may signal a problem of "hallucinating" the model Answer Relevance (Answer Relevance) This metric assesses how directly and adequately the generated answer answers the user's original question. Even if the answer is factually accurate, it may be useless if it does not answer the exact question that was asked. Uses the average cosine similarity between the original question and the questions generated from the answer Higher scores indicate better relevance Helps identify instances where the system deviates from the topic of the question 3- Context Precision This metric evaluates how effectively the information extraction component ranks relevant documents higher than irrelevant ones. High Context Precision means that the system retrieves exactly the documents that are needed for the answer. The range of values is from 0 to 1 Higher values indicate better accuracy Critical for the efficient use of the limited context window of the model Context Recall completeness (Context Recall) The completeness metric measures how well the extracted context matches the reference response. That is, whether the retrieved context contains all the necessary information to produce a complete and correct answer. It is scored from 0 to 1 Higher values indicate a better match to the reference truth Helps identify instances where the system is missing critical information Automate assessment with the Ragas library The Ragas library greatly simplifies the process of evaluating RAG systems against the above metrics. With it, developers can create a dataset containing questions, answers, and relevant contexts, and then evaluate them on multiple metrics simultaneously. This evaluation approach not only identifies current RAG system deficiencies, but also tracks progress as improvements are made to various components of the pipelines, from vector search to prompts for the generative model. Regular evaluation on these metrics should be an integral part of the development cycle of any RAG system, especially when deployed in mission-critical domains where accuracy and reliability of information are paramount. Example code: from ragas import SingleTurnSample from ragas.metrics import AspectCritic test_data = { "user_input": "summarise given text\nThe company reported an 8% rise in Q3 2024, driven by strong performance in the Asian market. Sales in this region have significantly contributed to the overall growth. Analysts attribute this success to strategic marketing and product localization. The positive trend in the Asian market is expected to continue into the next quarter.", "response": "The company experienced an 8% increase in Q3 2024, largely due to effective marketing strategies and product adaptation, with expectations of continued growth in the coming quarter.", } evaluator_llm = LangchainLLMWrapper(ChatOpenAI(model="gpt-4o")) metric = AspectCritic(name="summary_accuracy",llm=evaluator_llm, definition="Verify if the summary is accurate.") await metric.single_turn_ascore(SingleTurnSample(**test_data)) Repository Key RAG Challenges Modern RAG systems face several key challenges: Search relevance: Ensuring that the retrieved information is truly relevant to the query Information Integration: Effectively combining retrieved information from different sources Source quality: Identifying and utilizing reliable data sources Effective Prompting: Developing optimal prompts for the LLM using the extracted context Recent research Contextual extraction: a revolutionary improvement in RAG AI models often need access to specific knowledge to work effectively with users. For example, support chatbots need to know about a company's products, and legal assistants need to know about a set of case law. The traditional approach to augmenting model knowledge is Retrieval-Augmented Generation (RAG), which extracts relevant information from a knowledge base and adds it to the user's query. However, traditional RAG has a significant drawback: context is often lost during information processing, leading to failures in retrieving relevant data. Anthropic has presented a method that significantly improves the extraction phase in RAG systems. The method is called Contextual Retrieval and utilizes two sub-techniques: Contextual Embeddings (Contextual Embeddings) Contextual BM25. These techniques help preserve context when processing document fragments, which is critical for accurate information extraction. How does contextual extraction work? In traditional RAG, documents are broken into small fragments, which are then converted into vector embeddings or indexed for keyword search. The problem arises when the individual fragments don't contain enough context. For example, if you have a financial report with the phrase, "The company's revenue grew 3% from the previous quarter," without additional context, it's unclear which company is being talked about and for what period. Contextual extraction solves this problem by adding specific explanatory context to each snippet before creating embeddings or BM25-indexes: Original fragment = "The company's revenue increased by 3% compared to the previous quarter." Contextualized fragment = "This fragment is from an SEC report on ACME company's performance for Q2 2023; revenue for the previous quarter was $314 million. The company's revenue increased by 3% compared to the previous quarter. Experiments have shown that: Contextual embeddings reduced the frequency of failed retrievals of top-20 fragments by 35% (from 5.7% to 3.7%) The combination of contextual embeddings and contextual BM25 reduced the failure rate by 49% (from 5.7% to 2.9%) Adding a step of re-ranking the results reduced the failure rate by 67% (from 5.7% to 1.9%) Anthropic uses Claude to automate the process of adding context. A special prompt instructs the model to provide a short, fragment-specific context explaining its place in the overall document. The result is a short contextual text (50-100 tokens) that is added to the snippet before embeddings and BM25 indexes are created. Anthropic recommends: For small knowledge bases (less than 200,000 tokens, approximately 500 pages) - just include the entire knowledge base in the prompt. With the recently released prompt caching for Claude, this approach is much faster and more cost-effective. For larger knowledge bases - use contextual extraction, possibly combined with re-ranking for best results. LongRAG One interesting recent research is LongRAG, a RAG paradigm for dealing with long contexts in question answering. LongRAG addresses two major problems of traditional RAG systems: global structure breakdown when partitioned into chunks and the difficulty of identifying actual details among large amounts of noise.LongRAG includes four key components: a hybrid retriever, an LLM-enhanced information extractor, a CoT-guided filter, and an LLM-enhanced generator. The system works from two perspectives: extracting global information to understand structure and context, and extracting factual details for accurate answers. Experiments on several datasets with multi-way questions showed that LongRAG significantly outperforms both long context models (by 6.94%), advanced RAG systems (by 6.16%), and conventional Vanilla RAG (by 17.25%). Source ChunkRAG Conventional RAG systems often extract redundant or weakly relevant information, resulting in factual inaccuracies and hallucinations in the generated answers. Existing document retrieval approaches lack sufficient granularity to effectively filter irrelevant content. Researchers from Algoverse AI Research presented ChunkRAG, a new methodology that improves the information selection process through semantic segmentation and evaluation of text fragments. Instead of working with whole documents, the system divides them into semantically coherent fragments of variable length and evaluates the relevance of each fragment concerning a query. ChunkRAG works in two main steps: Semantic segmentation: the document is partitioned into sentences, which are grouped into semantically coherent blocks based on the cosine similarity of their vector representations. If the similarity between consecutive sentences falls below a threshold value (θ = 0.8), a new chunk is created. Hybrid search and advanced filtering: The system uses a combination of BM25 and LLM-based search, followed by a multi-level process to evaluate the relevance of each fragment. Fragments exceeding a certain similarity threshold (> 0.9) are removed as redundant. In experiments on PopQA, PubHealth, and Biography datasets, ChunkRAG performed better than state-of-the-art RAG methods. The system achieved 64.9% accuracy on PopQA, 77.3% on PubHealth, and a FactScore of 86.4% on Biography. The improvements are particularly notable in tasks requiring high factual accuracy, where even small irrelevant segments can cause the model to hallucinate. Despite the impressive results, ChunkRAG has some limitations, including high computational cost due to multi-level LLM estimation and slower processing time. Future research can focus on optimizing performance and investigating domain-specific thresholds for different types of tasks. HtmlRAG Traditionally, RAG systems use plain text as the format for extracted knowledge. However, researchers from China have proposed an innovative approach: using HTML instead of plain text. Why HTML is better than plain text for RAG systems: Preserves structural information of documents (headers, tables) Preserves semantic elements (code, a, and other tags) Most LLMs already can understand HTML markup Using HTML in RAGs causes some problems: Excessive size. HTML documents from web pages contain more than 80K tokens on average, and 90% of those tokens are CSS styles, JavaScript, and other elements not related to the main content. Noise in the data. Additional HTML elements can create noise that reduces the quality of LLM generation. To address these problems, the authors of the study proposed the HtmlRAG method, which includes: HTML Cleaning, a module for cleaning HTML from semantically irrelevant information Two-stage block-based HTML pruning: Trimming based on text embeddings Generative pruning based on smaller blocks Experimental results on six datasets for question-response systems confirm the superiority of HTML over plain text in RAG systems. FastRAG: an approach for dealing with semi-structured data Researchers at NIST presented a model called FastRAG, specifically designed to deal with semi-structured data such as network logs and configurations. Key benefits of FastRAG: Processing efficiency: FastRAG processes the raw data without having to send all the pieces through the LLM, which significantly reduces processing time and cost. Use of schemas and scripts: The system applies schemas and scripts to structure the data, making the information retrieval process more efficient. Integration of text and knowledge graph search: FastRAG integrates text search with knowledge graph queries, which improves the accuracy of information retrieval with context. Impressive results: Compared to existing methods such as GraphRAG, FastRAG shows improvements of up to 90% in time and up to 85% in processing cost. Astute RAG Retrieval-Augmented Generation (RAG) has become a standard approach for solving problems requiring extensive knowledge with large language models (LLMs). However, a recent study, "Astute RAG: Overcoming Imperfect Retrieval Augmentation and Knowledge Conflicts for Large Language Models," revealed a serious problem: imperfect retrieval can significantly reduce the performance of RAG systems. Researchers from Google Cloud AI Research and the University of Southern California found that approximately 70% of retrieved passages in real-world contexts do not contain direct answers to questions, resulting in poor performance of RAG- augmented LLMs. The central problem appeared to be a conflict between internal model knowledge and external information. The analysis showed that in about 19.2% of the cases there is a knowledge conflict when either the answer with or without RAG is correct. In this case, the internal knowledge of the model turns out to be correct in 47.4% of the conflict cases, while the external knowledge turns out to be correct in 52.6% of the cases. To overcome these problems, the authors proposed a new approach, Astute RAG, which: Adaptively extracts important information from the LLM's internal knowledge Iteratively combines internal and external knowledge in a source-aware manner Forms a final answer based on the reliability of the information Experiments with Gemini and Claude models demonstrated the superiority of Astute RAG over other RAG methods designed to improve robustness to retrieval errors. Notably, Astute RAG is the only approach that achieves or outperforms the performance of LLM without RAG even in worst-case scenarios. This research is particularly important for practical applications of RAG systems where search quality can vary. The ability to effectively combine internal model knowledge with external information allows for more robust and resilient AI systems to solve complex problems that require extensive and relevant knowledge. Source Rankify Recently, researchers from the University of Innsbruck introduced a new tool called Rankify, a comprehensive Python framework that combines search, reranking and generation processes using extracted data. Key features of Rankify: Modular architecture: Rankify offers a single interface for different RAG components, making it easy to experiment with different methods. Support for a variety of search methods: The tool integrates both sparse (BM25) and dense neural search methods (DPR, ANCE, BGE, Contriever, ColBERT). Advanced re-ranking capabilities: Rankify supports 24 re-ranking models with 41 sub-methods, including stream, pairwise, and list ranking. Pre-built datasets: The framework provides 40 pre-processed datasets for testing and comparing different RAG approaches. Evaluation Tools: Built-in metrics for evaluating search quality, reranking, and response generation. Available rerankers: # BM25 retrieval on Wikipedia bm25_retriever_wiki = Retriever(method="bm25", n_docs=5, index_type="wiki") # BM25 retrieval on MS MARCO bm25_retriever_msmacro = Retriever(method="bm25", n_docs=5, index_type="msmarco") # DPR (multi-encoder) retrieval on Wikipedia dpr_retriever_wiki = Retriever(method="dpr", model="dpr-multi", n_docs=5, index_type="wiki") # DPR (multi-encoder) retrieval on MS MARCO dpr_retriever_msmacro = Retriever(method="dpr", model="dpr-multi", n_docs=5, index_type="msmarco") # DPR (single-encoder) retrieval on Wikipedia dpr_retriever_wiki = Retriever(method="dpr", model="dpr-single", n_docs=5, index_type="wiki") # DPR (single-encoder) retrieval on MS MARCO dpr_retriever_msmacro = Retriever(method="dpr", model="dpr-single", n_docs=5, index_type="msmarco") # ANCE retrieval on Wikipedia ance_retriever_wiki = Retriever(method="ance", model="ance-multi", n_docs=5, index_type="wiki") # ANCE retrieval on MS MARCO ance_retriever_msmacro = Retriever(method="ance", model="ance-multi", n_docs=5, index_type="msmarco") # Contriever retrieval on Wikipedia contriever_retriever_wiki = Retriever(method="contriever", model="facebook/contriever-msmarco", n_docs=5, index_type="wiki") # Contriever retrieval on MS MARCO contriever_retriever_msmacro = Retriever(method="contriever", model="facebook/contriever-msmarco", n_docs=5, index_type="msmarco") # ColBERT retrieval on Wikipedia colbert_retriever_wiki = Retriever(method="colbert", model="colbert-ir/colbertv2.0", n_docs=5, index_type="wiki") # ColBERT retrieval on MS MARCO colbert_retriever_msmacro = Retriever(method="colbert", model="colbert-ir/colbertv2.0", n_docs=5, index_type="msmarco") # BGE retrieval on Wikipedia bge_retriever_wiki = Retriever(method="bge", model="BAAI/bge-large-en-v1.5", n_docs=5, index_type="wiki") # BGE retrieval on MS MARCO bge_retriever_msmacro = Retriever(method="bge", model="BAAI/bge-large-en-v1.5", n_docs=5, index_type="msmarco") # Hyde retrieval on Wikipedia hyde_retriever_wiki = Retriever(method="hyde" , n_docs=5, index_type="wiki", api_key=OPENAI_API_KEY ) # Hyde retrieval on MS MARCO hyde_retriever_msmacro = Retriever(method="hyde", n_docs=5, index_type="msmarco", api_key=OPENAI_API_KEY) Researchers have extensively tested Rankify on a variety of datasets. Particularly interesting are the results comparing different search models and their impact on response generation accuracy: For the Natural Questions (NQ) dataset, DPR combined with LLaMA V3 8B performed best, achieving an accuracy of 28.08% For TriviaQA, BM25 with the Gemma 2 9B model was the most efficient (57.55%) On the WebQuestions set, DPR with LLaMA V3 8B was again in the lead (19.83%) This demonstrates that the choice of the optimal search and generation strategy depends on the specific task and dataset. Repository From Native RAG to Agent-based RAG In today's world of artificial intelligence, Retrieval-Augmented Generation (RAG) technology has become one of the key approaches to information processing. However, classical RAG is being replaced by a new paradigm, Agentic RAG, which represents a significant step forward in intelligent document processing. Native RAG, which is widely used today, is a sequential process involving information extraction, information ranking, synthesis and response generation. This approach combines the extraction and generation techniques to provide accurate and contextually relevant answers. Agent-based RAG takes this concept to a whole new level. It is an advanced approach based on using autonomous agents to process and analyze multiple documents in a coordinated manner. It allows comparing different documents, generating specialized summaries and comparing different summaries of information. The Agent RAG architecture is based on two main types of components: Document Agents: Each document is assigned a dedicated agent capable of answering questions and producing summaries within its document. These agents act as experts on specific content. Meta-Agent: A top-level agent that coordinates the work of all document agents, orchestrating their interactions and integrating their outputs to form a cohesive and comprehensive response. Agent-based RAG has several significant advantages over traditional approaches: Autonomy: Agents act independently to extract, process, and generate information, which greatly increases the scalability of the system. Adaptability: The system is able to adjust strategies based on new data and changing contexts, making it more flexible in real-world usage scenarios. Proactivity: Agents can anticipate needs and take proactive actions to achieve goals, which improves the overall system performance. Agent-based RAG is particularly useful in scenarios that require careful and nuanced information processing and decision making. These may include: Analyzing large volumes of scientific publications Legal research and precedent analysis Financial analysis and forecasting Medical diagnostics based on heterogeneous data sources Conclusions RAG represents an important approach in modern AI technologies, combining information retrieval with the generative power of large language models. Here are the main conclusions from the paper: RAG is not a stand-alone technology but a comprehensive architecture with three key components: data ingestion, information retrieval, and a query component to deal with LLMs. Evaluating RAG systems requires an integrated approach using four key metrics: information accuracy (Faithfulness), response relevance, context accuracy, and context completeness. Recent research on RAGs includes innovative approaches: Contextual Extraction (from Anthropic) LongRAG for dealing with long contexts ChunkRAG to improve the relevance of extracted fragments HtmlRAG for preserving structural information FastRAG for efficient handling of semi-structured data Astute RAG to address the problem of knowledge conflicts Agent-based RAG represents the next evolutionary step in the development of this technology, utilizing autonomous agents to process information from multiple documents in a coordinated manner. The main challenges of RAG systems include search relevance, integration of information from different sources, source quality, and efficient prompting. These improvements enable RAGs to provide more accurate, fact-based answers, overcoming the limitations of traditional language models. ### Retrieval-Augmented Generation (RAG): Последние Исследования и Вызовы В современном мире AI-технологий Retrieval-Augmented Generation (RAG) становится все более значимым подходом, сочетающим возможности информационного поиска с генеративными способностями больших языковых моделей (LLM). Это позволяет преодолеть ряд ограничений, с которыми сталкиваются традиционные LLM, и обеспечить более точные и основанные на фактах ответы. Что такое RAG? RAG — это не отдельная технология, а целый "зонтик" различных компонентов, дизайнерских решений и адаптаций для конкретных доменов. Типичная RAG-система включает: Компонент приема данных: где данные обрабатываются, встраиваются и сохраняются как контекстные документы в векторной базе данных Компонент извлечения: где контекстные документы извлекаются и ранжируются по релевантности запросу Компонент запроса: где промпт с запросом комбинируется с результатами поиска и отправляется в LLM Методология оценки RAG-систем Недавние исследования, включая работу Саймона и коллег из Лейпцигского университета, предлагают методологическую основу для оценки RAG-систем. Их подход включает: Независимые переменные: архитектура RAG (модели встраивания, методы поиска, фильтры) и источники контекста Зависимые переменные: метрики эффективности RAG Оценка: сравнение с базовой моделью (обычно ванильной LLM) и использование бенчмарков Улучшения: анализ ошибок и систематические улучшения Одним из важнейших аспектов разработки успешной системы Retrieval-Augmented Generation (RAG) является её оценка с использованием объективных метрик. Без надлежащего измерения производительности невозможно определить, действительно ли система работает как задумано и где требуются улучшения. Четыре ключевые метрики для оценки RAG-систем Существует четыре основные метрики, которые следует использовать для всесторонней оценки вашего RAG-пайплайна: Точность информации (Faithfulness) Метрика точности информации измеряет, насколько сгенерированный ответ фактически соответствует предоставленному контексту. По сути, эта метрика показывает, не придумывает ли модель факты, которых нет в извлеченных документах. Оценивается по шкале от 0 до 1 Более высокие значения указывают на лучшую фактическую точность Низкий показатель может сигнализировать о проблеме "галлюцинаций" модели Релевантность ответа (Answer Relevance) Эта метрика оценивает, насколько прямо и адекватно сгенерированный ответ отвечает на исходный вопрос пользователя. Даже если ответ фактически точен, он может быть бесполезен, если не отвечает именно на тот вопрос, который был задан. Использует среднее косинусное сходство между исходным вопросом и вопросами, сгенерированными на основе ответа Высокие показатели указывают на лучшую релевантность Помогает выявить случаи, когда система отклоняется от темы вопроса Точность контекста (Context Precision) Данная метрика оценивает, насколько эффективно компонент извлечения информации ранжирует релевантные документы выше, чем нерелевантные. Высокая точность контекста означает, что система извлекает именно те документы, которые необходимы для ответа. Диапазон значений от 0 до 1 Более высокие значения указывают на лучшую точность Критически важна для эффективного использования ограниченного контекстного окна модели Полнота контекста (Context Recall) Метрика полноты измеряет, насколько хорошо извлеченный контекст соответствует эталонному ответу. То есть, содержит ли найденный контекст всю необходимую информацию для составления полного и правильного ответа. Оценивается от 0 до 1 Высокие значения указывают на лучшее соответствие эталонной истине Помогает выявить случаи, когда система упускает критически важную информацию Автоматизация оценки с библиотекой Ragas Библиотека Ragas значительно упрощает процесс оценки RAG-систем по вышеперечисленным метрикам. С её помощью разработчики могут создать набор данных, содержащий вопросы, ответы и соответствующие контексты, а затем оценить их по нескольким метрикам одновременно. Такой подход к оценке позволяет не только выявить текущие недостатки RAG-системы, но и отслеживать прогресс при внесении улучшений в различные компоненты пайплайна — от векторного поиска до промптов для генеративной модели. Регулярная оценка по этим метрикам должна стать неотъемлемой частью цикла разработки любой RAG-системы, особенно при внедрении в критически важные домены, где точность и надежность информации имеют первостепенное значение. Пример кода: from ragas import SingleTurnSample from ragas.metrics import AspectCritic test_data = { "user_input": "summarise given text\nThe company reported an 8% rise in Q3 2024, driven by strong performance in the Asian market. Sales in this region have significantly contributed to the overall growth. Analysts attribute this success to strategic marketing and product localization. The positive trend in the Asian market is expected to continue into the next quarter.", "response": "The company experienced an 8% increase in Q3 2024, largely due to effective marketing strategies and product adaptation, with expectations of continued growth in the coming quarter.", } evaluator_llm = LangchainLLMWrapper(ChatOpenAI(model="gpt-4o")) metric = AspectCritic(name="summary_accuracy",llm=evaluator_llm, definition="Verify if the summary is accurate.") await metric.single_turn_ascore(SingleTurnSample(**test_data)) Репозиторий Основные вызовы RAG Современные RAG-системы сталкиваются с несколькими ключевыми вызовами: Релевантность поиска: Обеспечение того, чтобы извлеченная информация была действительно релевантна запросу Интеграция информации: Эффективное объединение найденной информации из разных источников Качество источников: Определение и использование надежных источников данных Эффективное промптирование: Разработка оптимальных промптов для LLM с использованием извлеченного контекста Последние исследования Контекстуальное извлечение: революционное улучшение в RAG Для эффективной работы с пользователями AI-модели часто нуждаются в доступе к специфическим знаниям. Например, чат-боты поддержки должны знать о продуктах компании, а юридические ассистенты — о множестве прецедентов. Традиционный подход к расширению знаний модели — это Retrieval-Augmented Generation (RAG), который извлекает релевантную информацию из базы знаний и добавляет её в запрос пользователя. Однако у традиционного RAG есть существенный недостаток: при обработке информации часто теряется контекст, что приводит к неудачам при извлечении нужных данных. Anthropic представила метод, значительно улучшающий этап извлечения в RAG-системах. Метод называется "Контекстуальное извлечение" (Contextual Retrieval) и использует две подтехники: Контекстуальные эмбеддинги (Contextual Embeddings) Контекстуальный BM25 (Contextual BM25) Эти техники помогают сохранить контекст при обработке фрагментов документов, что критически важно для точного извлечения информации. Как работает контекстуальное извлечение? В традиционном RAG документы разбиваются на маленькие фрагменты, которые затем преобразуются в векторные эмбеддинги или индексируются для поиска по ключевым словам. Проблема возникает, когда отдельные фрагменты не содержат достаточного контекста. Например, если у вас есть финансовый отчет с фразой: "Выручка компании выросла на 3% по сравнению с предыдущим кварталом", то без дополнительного контекста непонятно, о какой компании идет речь и за какой период. Контекстуальное извлечение решает эту проблему, добавляя к каждому фрагменту специфический поясняющий контекст перед созданием эмбеддингов или BM25-индекса: Оригинальный фрагмент = "Выручка компании выросла на 3% по сравнению с предыдущим кварталом." Контекстуализированный фрагмент = "Этот фрагмент из отчета SEC о показателях компании ACME за 2 квартал 2023; выручка за предыдущий квартал составила $314 миллионов. Выручка компании выросла на 3% по сравнению с предыдущим кварталом." Эксперименты показали, что: Контекстуальные эмбеддинги снизили частоту неудачных извлечений топ-20 фрагментов на 35% (с 5.7% до 3.7%) Комбинация контекстуальных эмбеддингов и контекстуального BM25 снизила частоту неудач на 49% (с 5.7% до 2.9%) При добавлении этапа ре-ранжирования результатов, частота неудач снизилась на 67% (с 5.7% до 1.9%) Для автоматизации процесса добавления контекста Anthropic использует Claude. Специальный промпт инструктирует модель предоставлять краткий, специфический для фрагмента контекст, объясняющий его место в общем документе. Результат — короткий контекстуальный текст (50-100 токенов), который добавляется к фрагменту перед созданием эмбеддингов и BM25-индекса. Anthropic рекомендует: Для небольших баз знаний (менее 200,000 токенов, примерно 500 страниц) — просто включайте всю базу знаний в промпт. С недавно выпущенным кэшированием промптов для Claude этот подход стал значительно быстрее и экономичнее. Для более крупных баз знаний — используйте контекстуальное извлечение, возможно в сочетании с ре-ранжированием для достижения наилучших результатов. LongRAG Одним из интересных недавних исследований является LongRAG — парадигма RAG, предназначенная для работы с длинными контекстами при ответах на вопросы. LongRAG решает две основные проблемы традиционных RAG-систем: разрыв глобальной структуры при разбиении на чанки и сложность идентификации фактических деталей среди большого объема шума. LongRAG включает четыре ключевых компонента: гибридный ретривер, LLM-расширенный экстрактор информации, CoT-управляемый фильтр и LLM-расширенный генератор. Система работает с двух перспектив: извлечение глобальной информации для понимания структуры и контекста, а также извлечение фактических деталей для точных ответов. Эксперименты на нескольких датасетах с многоходовыми вопросами показали, что LongRAG значительно превосходит как модели с длинным контекстом (на 6.94%), так и передовые RAG-системы (на 6.16%) и обычный Vanilla RAG (на 17.25%). Источник ChunkRAG Традиционные RAG-системы часто извлекают избыточную или слабо релевантную информацию, что приводит к фактическим неточностям и галлюцинациям в генерируемых ответах. Существующие подходы к документальному поиску не обладают достаточной гранулярностью для эффективной фильтрации несущественного контента. Исследователи из Algoverse AI Research представили ChunkRAG - новую методологию, которая улучшает процесс отбора информации через семантическую сегментацию и оценку фрагментов текста. Вместо работы с целыми документами система разделяет их на семантически связные фрагменты переменной длины и оценивает релевантность каждого фрагмента по отношению к запросу. ChunkRAG работает в два основных этапа: Семантическая сегментация: Документ разбивается на предложения, которые группируются в семантически связные блоки на основе косинусного сходства их векторных представлений. Если сходство между последовательными предложениями падает ниже порогового значения (θ = 0,8), создается новый фрагмент. Гибридный поиск и расширенная фильтрация: Система использует комбинацию BM25 и поиска на основе LLM с последующим многоуровневым процессом оценки релевантности каждого фрагмента. Фрагменты, превышающие определенный порог сходства (> 0,9), удаляются как избыточные. В экспериментах на датасетах PopQA, PubHealth и Biography, ChunkRAG продемонстрировал лучшие результаты по сравнению с современными RAG-методами. На PopQA система достигла точности 64,9%, на PubHealth - 77,3%, а на Biography - оценку FactScore 86,4%. Особенно заметны улучшения в задачах, требующих высокой фактической точности, где даже небольшие нерелевантные сегменты могут привести к галлюцинациям модели. Несмотря на впечатляющие результаты, ChunkRAG имеет некоторые ограничения, включая высокие вычислительные затраты из-за многоуровневой оценки LLM и более медленное время обработки. Будущие исследования могут быть направлены на оптимизацию производительности и исследование доменно-специфических пороговых значений для различных типов задач. HtmlRAG Традиционно RAG-системы используют обычный текст (plain text) в качестве формата для извлеченных знаний. Однако исследователи из Китая предложили инновационный подход: использовать HTML вместо обычного текста. Почему HTML лучше обычного текста для RAG-систем: Сохраняет структурную информацию документов (заголовки, таблицы) Сохраняет семантические элементы (теги code, a и другие) Большинство LLM уже обладают способностью понимать HTML-разметку Использование HTML в RAG вызывает ряд проблем: Избыточный размер. HTML-документы с веб-страниц содержат в среднем более 80K токенов, причем 90% из них — это CSS-стили, JavaScript и другие элементы, не относящиеся к основному содержанию. Шум в данных. Дополнительные элементы HTML могут создавать шум, который снижает качество генерации LLM. Для решения этих проблем авторы исследования предложили метод HtmlRAG, который включает: HTML Cleaning — модуль очистки HTML от семантически нерелевантной информации Двухэтапное блочное обрезание HTML: Обрезание на основе текстовых эмбеддингов Генеративное обрезание на основе более мелких блоков Результаты экспериментов на шести наборах данных для вопросно-ответных систем подтверждают превосходство HTML над обычным текстом в RAG-системах FastRAG: подход к работе с полуструктурированными данными Исследователи из NIST представили модель под названием FastRAG, специально разработанную для работы с полуструктурированными данными, такими как сетевые логи и конфигурации. Ключевые преимущества FastRAG: Эффективность обработки: FastRAG обрабатывает исходные данные без необходимости отправки всех фрагментов через LLM, что значительно сокращает время и стоимость обработки. Использование схем и скриптов: Система применяет схемы и скрипты для структурирования данных, что делает процесс извлечения информации более эффективным. Интеграция поиска по тексту и графу знаний: FastRAG объединяет текстовый поиск с запросами к графам знаний, что повышает точность извлечения информации с контекстом. Впечатляющие результаты: По сравнению с существующими методами, такими как GraphRAG, FastRAG демонстрирует улучшение до 90% по времени и до 85% по стоимости обработки. Astute RAG Retrieval-Augmented Generation (RAG) стал стандартным подходом для решения задач, требующих обширных знаний с помощью больших языковых моделей (LLM). Однако недавнее исследование "Astute RAG: Overcoming Imperfect Retrieval Augmentation and Knowledge Conflicts for Large Language Models" выявило серьезную проблему: несовершенный поиск может значительно снизить эффективность RAG-систем. Исследователи из Google Cloud AI Research и Университета Южной Калифорнии обнаружили, что примерно 70% извлеченных пассажей в реальных условиях не содержат прямых ответов на вопросы, что приводит к снижению производительности LLM с RAG-дополнением. Центральной проблемой оказался конфликт между внутренними знаниями модели и внешней информацией. Анализ показал, что примерно в 19,2% случаев возникает конфликт знаний, когда либо ответ с использованием RAG, либо без него является корректным. При этом внутренние знания модели оказываются правильными в 47,4% случаев конфликта, а внешние знания — в 52,6%. Для преодоления этих проблем авторы предложили новый подход — Astute RAG, который: Адаптивно извлекает важную информацию из внутренних знаний LLM Итеративно объединяет внутренние и внешние знания с учетом источников Формирует окончательный ответ на основе надежности информации Эксперименты с моделями Gemini и Claude продемонстрировали превосходство Astute RAG над другими методами RAG, созданными для повышения устойчивости к ошибкам поиска. Примечательно, что Astute RAG — единственный подход, который достигает или превосходит производительность LLM без RAG даже в наихудших сценариях. Эти исследования особенно важны для практических применений RAG-систем, где качество поиска может варьироваться. Умение эффективно сочетать внутренние знания моделей с внешней информацией позволяет создавать более надежные и устойчивые системы искусственного интеллекта для решения сложных задач, требующих обширных и актуальных знаний. Источник Rankify Недавно исследователи из Университета Инсбрука представили новый инструмент под названием Rankify — комплексный Python-фреймворк, объединяющий процессы поиска, переранжирования и генерации с использованием извлеченных данных. Ключевые особенности Rankify: Модульная архитектура: Rankify предлагает единый интерфейс для различных компонентов RAG-систем, что позволяет легко экспериментировать с разными методами. Поддержка разнообразных методов поиска: Инструмент интегрирует как разреженные (BM25), так и плотные нейронные методы поиска (DPR, ANCE, BGE, Contriever, ColBERT). Расширенные возможности переранжирования: Rankify поддерживает 24 модели переранжирования с 41 под-методом, включая поточечное, попарное и списочное ранжирование. Готовые наборы данных: Фреймворк предоставляет 40 предварительно обработанных наборов данных для тестирования и сравнения различных RAG-подходов. Инструменты оценки: Встроенные метрики для оценки качества поиска, переранжирования и генерации ответов. Доступные rerankers: # BM25 retrieval on Wikipedia bm25_retriever_wiki = Retriever(method="bm25", n_docs=5, index_type="wiki") # BM25 retrieval on MS MARCO bm25_retriever_msmacro = Retriever(method="bm25", n_docs=5, index_type="msmarco") # DPR (multi-encoder) retrieval on Wikipedia dpr_retriever_wiki = Retriever(method="dpr", model="dpr-multi", n_docs=5, index_type="wiki") # DPR (multi-encoder) retrieval on MS MARCO dpr_retriever_msmacro = Retriever(method="dpr", model="dpr-multi", n_docs=5, index_type="msmarco") # DPR (single-encoder) retrieval on Wikipedia dpr_retriever_wiki = Retriever(method="dpr", model="dpr-single", n_docs=5, index_type="wiki") # DPR (single-encoder) retrieval on MS MARCO dpr_retriever_msmacro = Retriever(method="dpr", model="dpr-single", n_docs=5, index_type="msmarco") # ANCE retrieval on Wikipedia ance_retriever_wiki = Retriever(method="ance", model="ance-multi", n_docs=5, index_type="wiki") # ANCE retrieval on MS MARCO ance_retriever_msmacro = Retriever(method="ance", model="ance-multi", n_docs=5, index_type="msmarco") # Contriever retrieval on Wikipedia contriever_retriever_wiki = Retriever(method="contriever", model="facebook/contriever-msmarco", n_docs=5, index_type="wiki") # Contriever retrieval on MS MARCO contriever_retriever_msmacro = Retriever(method="contriever", model="facebook/contriever-msmarco", n_docs=5, index_type="msmarco") # ColBERT retrieval on Wikipedia colbert_retriever_wiki = Retriever(method="colbert", model="colbert-ir/colbertv2.0", n_docs=5, index_type="wiki") # ColBERT retrieval on MS MARCO colbert_retriever_msmacro = Retriever(method="colbert", model="colbert-ir/colbertv2.0", n_docs=5, index_type="msmarco") # BGE retrieval on Wikipedia bge_retriever_wiki = Retriever(method="bge", model="BAAI/bge-large-en-v1.5", n_docs=5, index_type="wiki") # BGE retrieval on MS MARCO bge_retriever_msmacro = Retriever(method="bge", model="BAAI/bge-large-en-v1.5", n_docs=5, index_type="msmarco") # Hyde retrieval on Wikipedia hyde_retriever_wiki = Retriever(method="hyde" , n_docs=5, index_type="wiki", api_key=OPENAI_API_KEY ) # Hyde retrieval on MS MARCO hyde_retriever_msmacro = Retriever(method="hyde", n_docs=5, index_type="msmarco", api_key=OPENAI_API_KEY) Исследователи провели обширное тестирование Rankify на различных наборах данных. Особенно интересны результаты сравнения различных моделей поиска и их влияния на точность генерации ответов: Для набора данных Natural Questions (NQ) лучшие результаты показал DPR в сочетании с LLaMA V3 8B, достигая точности 28.08% Для TriviaQA наиболее эффективным оказался BM25 с моделью Gemma 2 9B (57.55%) На наборе WebQuestions снова лидировал DPR с LLaMA V3 8B (19.83%) Это демонстрирует, что выбор оптимальной стратегии поиска и генерации зависит от конкретной задачи и набора данных. Репозиторий От Нативного RAG к Агентскому RAG В современном мире искусственного интеллекта технология Retrieval-Augmented Generation (RAG) стала одним из ключевых подходов к обработке информации. Однако на смену классическому RAG приходит новая парадигма — Агентский RAG (Agentic RAG), представляющий собой значительный шаг вперед в области интеллектуальной обработки документов. Нативный RAG, который широко используется сегодня, представляет собой последовательный процесс, включающий извлечение информации, ее ранжирование, синтез и генерацию ответа. Этот подход объединяет методы извлечения и генерации для предоставления точных и контекстуально релевантных ответов. Агентский RAG выводит эту концепцию на качественно новый уровень. Это продвинутый подход, основанный на использовании автономных агентов для обработки и анализа множества документов скоординированным образом. Он позволяет сравнивать различные документы, составлять специализированные резюме и сопоставлять различные сводки информации. Архитектура Агентского RAG основана на двух основных типах компонентов: Агенты документов: Каждому документу назначается выделенный агент, способный отвечать на вопросы и составлять резюме в рамках своего документа. Эти агенты действуют как эксперты по конкретному контенту. Мета-агент: Агент верхнего уровня, который координирует работу всех агентов документов, оркестрируя их взаимодействие и интегрируя их выводы для формирования связного и всеобъемлющего ответа. Агентский RAG обладает рядом существенных преимуществ по сравнению с традиционными подходами: Автономность: Агенты действуют независимо для извлечения, обработки и генерации информации, что значительно увеличивает масштабируемость системы. Адаптивность: Система способна корректировать стратегии на основе новых данных и изменяющихся контекстов, что делает ее более гибкой в реальных сценариях использования. Проактивность: Агенты могут предвидеть потребности и предпринимать упреждающие действия для достижения целей, что повышает эффективность работы системы в целом. Агентский RAG особенно полезен в сценариях, требующих тщательной и нюансированной обработки информации и принятия решений. Это могут быть: Анализ больших массивов научных публикаций Юридические исследования и анализ прецедентов Финансовый анализ и прогнозирование Медицинская диагностика на основе разнородных источников данных Выводы RAG представляет собой важный подход в современных AI-технологиях, сочетающий информационный поиск с генеративными возможностями больших языковых моделей. Вот основные выводы из статьи: RAG — это не отдельная технология, а комплексная архитектура с тремя ключевыми компонентами: прием данных, извлечение информации и компонент запроса для работы с LLM. Оценка RAG-систем требует комплексного подхода с использованием четырех ключевых метрик: точность информации (Faithfulness), релевантность ответа, точность контекста и полнота контекста. Последние исследования в области RAG включают инновационные подходы: Контекстуальное извлечение (от Anthropic) LongRAG для работы с длинными контекстами ChunkRAG для улучшения релевантности извлеченных фрагментов HtmlRAG для сохранения структурной информации FastRAG для эффективной работы с полуструктурированными данными Astute RAG для решения проблемы конфликтов знаний Агентский RAG представляет следующий эволюционный шаг в развитии этой технологии, используя автономных агентов для обработки информации из множества документов скоординированным образом. Основные вызовы RAG-систем включают релевантность поиска, интеграцию информации из разных источников, качество источников и эффективное промптирование. Эти улучшения позволяют RAG-системам предоставлять более точные, основанные на фактах ответы, преодолевая ограничения традиционных языковых моделей. ### How to Speed Up LLMs and Reduce Costs: Edge Models RouteLLM reduces your costs for using LLMs by 3.6 times. It chooses whether to use a strong or weak LLM model depending on the complexity of the user's query. This optimizes the balance between cost and quality of the response. The Python library allows you to use this approach directly. import os from routellm.controller import Controller os.environ["OPENAI_API_KEY"] = "sk-XXXXXX" # Replace with your model provider, we use Anyscale's Mixtral here. os.environ["ANYSCALE_API_KEY"] = "esecret_XXXXXX" client = Controller( routers=["mf"], strong_model="gpt-4-1106-preview", weak_model="anyscale/mistralai/Mixtral-8x7B-Instruct-v0.1", ) Here’s how the model works: The model is trained on preference data collected from 80,000 "battles" on the Chatbot Arena platform. To combat data sparsity, the models are grouped into strong models from the top levels and weak ones from the third level. They test different routing approaches, including matrix factorization, a BERT classifier, weighted similarity ranking (SW), and a causal classifier Llama 3 with 8B parameters. Matrix factorization allows for a 3.66 reduction in costs while maintaining quality comparable to GPT-4. Routers generalize well across different strong and weak model pairs without needing retraining. For more details, you can read the article. Overview of Small Language Models (SLMs) An excellent overview of small language models (SLMs), including discussions on definitions, applications, improvements, reliability, and much more. Compact LLMs for Edge Devices Meta released quantized Llama 3.2 models with 1B and 3B parameters — an ideal choice for edge devices and deployments, focusing on privacy and speed while maintaining almost full accuracy! In brief: Based on Llama 3.2 with 1B and 3B parameters. 2–3 times faster than the original models during inference. Reduction in model size and memory usage by 45–60%. Maintains almost full accuracy. Uses 4-bit grouped quantization and 8-bit dynamic activation for optimal performance. The quantization scheme is designed with ExecuTorch from PyTorch and Arm CPU in mind. Best tasks: knowledge extraction, summarization, and instruction-following. Available on Hugging Face. Ministral 3B and Ministral 8B Mistral AI has announced the Ministraux: two advanced models for local and edge computing. Ministral 3B and 8B support a context length of up to 128k tokens, offering high performance and low latency. These models are perfect for tasks requiring privacy and high speed: from local analytics to autonomous robotics. Ministral 8B uses an innovative attention window to optimize memory usage, and both models can be tuned for processing data and API calls in agent workflows. These solutions offer an effective alternative for local tasks without an internet connection. Mistral again raises the bar in compact language models. Conclusion RouteLLM reduces LLM costs by 3.6 times, optimizing the selection between strong and weak models for different queries. Meta Llama 3.2 (1B and 3B parameters) are compact models for edge devices with a 45–60% reduction in memory usage while maintaining accuracy. Ministral 3B and 8B are high-performance models for local computing, supporting context up to 128k tokens, ideal for confidential tasks. ### Как ускорить LLM и снизить затраты. Edge модели RouteLLM снижает ваши расходы на использование LLM в 3,6 раз. Он выбирает, использовать ли сильную или слабую модель LLM, в зависимости от сложности пользовательского запроса. Это оптимизирует баланс между стоимостью и качеством ответа. Библиотека на Python позволяет использовать этот подход напрямую. import os from routellm.controller import Controller os.environ["OPENAI_API_KEY"] = "sk-XXXXXX" # Replace with your model provider, we use Anyscale's Mixtral here. os.environ["ANYSCALE_API_KEY"] = "esecret_XXXXXX" client = Controller( routers=["mf"], strong_model="gpt-4-1106-preview", weak_model="anyscale/mistralai/Mixtral-8x7B-Instruct-v0.1", ) Вот как работает модель: Модель обучена на данных предпочтений, собранных в 80 тысячах "баттлов" на платформе Chatbot Arena. Для борьбы с разреженностью данных модели сгруппированы по уровням: сильные модели из топовых уровней, а слабые — из третьего уровня. Они тестируют разные подходы маршрутизации, включая матричную факторизацию, классификатор BERT, ранжирование на основе взвешенного сходства (SW) и даже каузальный классификатор Llama 3 с 8B параметрами. Матричная факторизация позволяет снизить затраты до 3,66 раза при сохранении качества, сопоставимого с GPT-4. Маршрутизаторы хорошо обобщаются на различные пары сильных и слабых моделей без необходимости переобучения. Более подробно можно почитать в статье Обзор малых языковых моделей (SLMs) Отличный обзор малых языковых моделей (SLMs), включая обсуждение вопросов, связанных с определениями, применениями, улучшениями, надежностью и многим другим. Компактные LLM модели для edge-устройств Meta выпустила квантованные модели Llama 3.2 с 1B и 3B параметрами — идеальный выбор для работы на устройствах и edge-развертываний, с акцентом на конфиденциальность и скорость при сохранении почти полной точности! Кратко: Основаны на Llama 3.2 с 1B и 3B параметрами. В 2–3 раза быстрее оригинальных моделей при выводе. Снижение размера моделей и использования памяти на 45–60%. Сохраняют почти полную точность. Используют 4-битную группированную квантизацию и 8-битную динамическую активацию для оптимальной производительности. Квантизационная схема разработана с учетом ExecuTorch от PyTorch и Arm CPU. Лучшие задачи: извлечение знаний, суммаризация и следование инструкциям. Доступно на Hugging Face. Ministral 3B и Ministral 8B Компания Mistral AI анонсировала les Ministraux: две передовые модели для локальных и edge-вычислений. Ministral 3B и 8B поддерживают контекст до 128k токенов, отличаются высокой производительностью и низкой задержкой. Эти модели идеально подходят для задач, где требуется конфиденциальность и высокая скорость: от локальной аналитики до автономной робототехники. Ministral 8B использует инновационное окно внимания, оптимизируя работу с памятью, а обе модели могут быть настроены для обработки данных и API-вызовов в агентных рабочих процессах. Эти решения предлагают эффективную альтернативу для локальных задач без подключения к интернету. Mistral снова поднимает планку в области компактных языковых моделей. Вывод RouteLLM снижает расходы на LLM в 3,6 раза, оптимизируя выбор между сильной и слабой моделью для разных запросов. Meta Llama 3.2 (1B и 3B параметров) — компактные модели для edge-устройств с 45-60% снижением памяти при сохранении точности. Ministral 3B и 8B — высокопроизводительные модели для локальных вычислений, поддерживающие контекст до 128k токенов, идеально подходят для конфиденциальных задач. ### Курс Управление AI и ML продуктами AI и машинное обучение внедряются повсюду. Это мощная тенденция, трансформирующая цифровые продукты сегодня. Если вы хотите оставаться конкурентоспособными на рынке будущего, вам нужно научиться работать с AI. Алгоритмы машинного обучения могут использоваться для выявления аномалий на медицинских изображениях, для распознавания лиц и в других областях. Машинное обучение также активно используется в рекомендательных системах, чат-ботах и беспилотных автомобилях. По мере распространения и внедрения машинного обучения в компаниях, потребность в управлении продуктом компетентными в AI менеджерами будет неуклонно расти. Уровень подготовки: Начинающий 🟢 ⚪ ⚪ Алимбеков Ренат Руководитель в сфере анализа больших данных и машинном обучении. Проектирует и разрабатывает AI сервисы Участвовал в запуске ряда успешных продуктов сфере MedTech и биометрии 🚀 Опыт работы в Fintech, MedTech, AdTech и EduTech направлениях 👩‍💻 Кому полезен этот курс ✅  Product и Project менеджерам ✅  Фаундерам, создающим AI/ ML продукт ✅  IT специалистам, работающим в AI/ ML продуктах Чему вы научитесь Курс состоит из 10 занятий и разбора 3 кейсов из разных областей AI (Табличные данные, Computer Vision и Natural Language Processing): Кредитный скоринг Биометрия Работа с отзывами клиентов Это позволит вам получить обширные навыки для работы над практически любым ML-проектом. ✅  Понимать влияние и ограничения алгоритмов AI ✅  Понимать концепций алгоритмов и обучения моделей ✅  Разрабатывает стратегию запуска новых AI продуктов ✅  Распознавать возможности и потенциал внедрения AI продуктов ✅  Общаться на одном языке с Data-специалистами Для обучения не нужны навыки программирования или глубокое знание математики. Программа обучения 1. Введение в сферу Data science Что такое Data Science? Применение и кейсы Роль продакт/ проджект менеджера в AI продукте 2. Все про данные Что такое данные? Какие они бывают? Практическое домашнее задание Консультация по выполнению домашнего задания 3. Цикл ML проекта Как структурирован типичный ML проект Какие решения вам предстоит принять на каждом этапе Как распределить время этапов для вашей команды Практическое домашнее задание Консультация по выполнению домашнего задания 4. Метрики Основные метрики моделей AI Как оценивать модели машинного обучения Практическое домашнее задание Консультация по выполнению домашнего задания 5. Data Product Canvas Data Product Canvas Гипотеза Практическое домашнее задание Консультация по выполнению домашнего задания 6. Лучшие практики работы с ML командой Lean DS Бэклог Работа с гипотезами Практическое домашнее задание Консультация по выполнению домашнего задания 7. Бизнес-метрики в машинном обучение Прокси-метрики в машинном обучении Unit экономика Практическое домашнее задание Консультация по выполнению домашнего задания 8. User experience и деплой модели в production Интерпретируемость моделей Прототипирование Варианты деплоя моделей User experience Практическое домашнее задание Консультация по выполнению домашнего задания 9. A/B тест Введение в A/B тестирование Подходы к проведению A/B тестов Практическое домашнее задание Консультация по выполнению домашнего задания 10. Защита диплома Презентация и защита проекта Стоимость Мы гарантируем возврат денег. Если в течение первой недели вы поймете, что курс вам не подходит, — напишите нам, и мы вернем полную стоимость без выяснения причин. Для оформления возврата с момента оплаты должно пройти не больше 7 календарных дней. 🎉 Специальное предложение: Скидка 15% на предзаказ! 🎉 Забронируйте свое место на курсе "Управление AI и ML продуктами" прямо сейчас и получите эксклюзивную скидку 15% от стоимости обучения. • Основной тариф: 69 900 ₽ 59 415 ₽ • Тариф с ментором: 99 900 ₽ 84 915 ₽ Торопитесь! Предложение ограничено по времени. Основной тариф 69 900 ₽ / 715 $ / 347 000 ₸ 10 занятий 3 кейса Проверка домашних заданий Безлимитный доступ ко всему контенту Неограниченный доступ к материалам после окончания обучения С ментором 99 900 ₽ / 1 020 $ / 496 000 ₸ 10 занятий 3 кейса Проверка домашних заданий Безлимитный доступ ко всему контенту Неограниченный доступ к материалам после окончания обучения Поддержка ментора в процессе обучения Часовая Live Q&A сессия в неделю Двухчасовой one on one менторинг в неделю FAQ Вы предоставляете сертификат о завершении курса: Нет Как устроен процесс: Каждую неделю проходят 3 занятия - лекция, ответы на вопросы по домашнему заданию и разбор домашнего задания Есть ли специальные требования к компьютеру: Нет Может ли обучение оплатить компания: Да мы принимаем платежи от компаний Сколько длится обучение: Примерно 60 часов Как проверяют задания: Задания проверяет автор курса, в конце каждого блока будет разбор всех заданий Нужны ли навыки программирования или математики: Нет Остались вопросы? Напишите нам на alimbekovr@hotmail.com и мы ответим. ### Trending Articles on Large Language Models Google DeepMind has developed a multi-pass online approach using reinforcement learning to enhance the self-correction capabilities of large language models (LLMs). It has been shown that supervised fine-tuning (SFT) is ineffective for learning self-correction and faces a mismatch between training data and the model’s responses. To address this issue, a two-stage approach is proposed, which first optimizes self-correction behavior and then uses an additional reward to reinforce self-correction during training. This method relies entirely on data generated by the model itself. When applied to the Gemini 1.0 Pro and 1.5 Flash models, it achieved record-breaking self-correction performance, improving the baseline models by 15.6% and 9.1%, respectively, in MATH and HumanEval tests. Comprehensive Evaluation of Quantized LLMs Tuned for Instruction-Following This study evaluates the performance of LLMs trained for instruction-following under different quantization methods for models with parameters ranging from 7B to 405B. Key findings from the study: Quantizing a larger LLM to a similar size as a smaller FP16 LLM generally yields better results on most tests. Performance varies significantly depending on the quantization methods, model size, and bit depth. Methods using weight-only quantization often deliver the best results for larger models. The complexity of tasks does not significantly affect the reduction in accuracy caused by quantization. Do Large Language Models (LLMs) Have Memory? According to current results, LLMs do indeed demonstrate memory. But what is the mechanism behind this memory? The article explores LLMs' memory capabilities, using the Universal Approximation Theorem (UAT) to explain their memory mechanism. It also proposes a new approach to evaluating LLM performance by comparing the memory capacities of different models. The Transformer architecture operates as a dynamic approximation model under UAT, with a high capacity to adapt to input data. As a result, LLMs can recall entire content based on minimal input information. Since this memory can only be verified when activated by input data, we call it "Schrödinger’s Memory." Logic-of-Thought for Comprehensive Reasoning in LLMs Logic-of-Thought (LoT) is a new prompting technique that uses propositional logic to generate and add enhanced logical information from the input context. LoT improves Chain-of-Thought (CoT) performance on the ReClor dataset by +4.35%, increases CoT+SelfConsistency efficiency on LogiQA by +5%, and enhances ToT results on the ProofWriter dataset by +8%. Conclusion Self-correction in LLMs through reinforcement learning: Google DeepMind proposed an innovative approach to enhance the self-correction capabilities of large language models (LLMs), improving the Gemini models by 15.6% and 9.1% in MATH and HumanEval tests, respectively. This highlights the significant potential of using model-generated data in LLM training. Quantization of LLMs for instruction-following: Quantization methods have a substantial impact on LLM performance, with quantizing larger models (405B parameters) often yielding better results. Memory in LLMs: It has been proven that LLMs possess memory, and the Transformer architecture functions as an approximation mechanism for input data, demonstrating "Schrödinger’s Memory," which is activated by the input. Logic-of-Thought for improving LLM reasoning: The new Logic-of-Thought (LoT) approach showed significant improvements in LLM performance on logical reasoning tasks, particularly on the ReClor, LogiQA, and ProofWriter datasets, confirming the effectiveness of using logical structures to enhance model performance. Together, these studies emphasize the importance of adapting existing LLMs and implementing new approaches to improve their performance in tasks involving self-correction, quantization, memory, and logical reasoning. ### Трендовые статьи по Large Language Model Google Deepmind разработали многократный онлайн-подход с использованием обучения с подкреплением (reinforcement learning), чтобы улучшить способность больших языковых моделей (LLM) к самокоррекции. Показано, что обучение с учителем (SFT) неэффективно для изучения самокоррекции и сталкивается с несоответствием между данными для обучения и ответами модели. Для решения этой проблемы предлагается двухэтапный подход, который сначала оптимизирует поведение самокоррекции, а затем использует дополнительное вознаграждение для усиления самокоррекции в процессе обучения. Этот метод полностью основан на данных, сгенерированных самой моделью. При применении к моделям Gemini 1.0 Pro и 1.5 Flash достигается рекордная производительность по самокоррекции, улучшая базовые модели на 15.6% и 9.1% соответственно в тестах MATH и HumanEval. Комплексная оценка квантованных LLM, настроенных на выполнение инструкций В данной работе оценивается производительность LLM, обученных на выполнении инструкций, при различных методах квантования для моделей размером от 7B до 405B параметров. Ключевые выводы (из статьи): Квантование большей модели LLM до аналогичного размера, как у меньшей FP16 LLM, обычно даёт лучшие результаты на большинстве тестов. Производительность значительно варьируется в зависимости от методов квантования, размера модели и глубины битности, причём методы, использующие квантование только весов, часто обеспечивают лучшие результаты для более крупных моделей. Сложность задачи не оказывает значительного влияния на снижение точности, вызванное квантованием. Есть ли память у больших языковых моделей (LLM) Судя по текущим результатам, LLM действительно демонстрируют наличие памяти. Так в чём же заключается механизм этой памяти? В статье рассматриваются возможности памяти больших языковых моделей (LLM). Она использует Теорему универсальной аппроксимации (Universal Approximation Theorem) для объяснения механизма памяти LLM. Также предлагается новый подход к оценке производительности LLM, сравнивая емкости памяти различных моделей. Архитектура Transformer функционирует как динамическая модель аппроксимации UAT, обладающая высокой способностью адаптивно подстраиваться под входные данные. В результате LLM способны вспоминать целый контент на основе минимальной информации на входе. Поскольку эта память может быть подтверждена только при активации входными данными, мы называем её «памятью Шрёдингера». Logic-of-Thought для полного рассуждения в LLM Предлагается новая техника подсказок под названием Logic-of-Thought (LoT), которая использует пропозициональную логику для генерации и добавления расширенной логической информации из контекста ввода. LoT улучшает производительность Chain-of-Thought (CoT) на наборе данных ReClor на +4,35%. Также повышает эффективность CoT+SelfConsistency на LogiQA на +5% и улучшает результаты ToT на наборе данных ProofWriter на +8%. Вывод Самокоррекция в LLM через обучение с подкреплением: Google Deepmind предложили инновационный подход для повышения способности больших языковых моделей (LLM) к самокоррекции, улучшив базовые модели Gemini на 15,6% и 9,1% в тестах MATH и HumanEval соответственно. Это показывает значительный потенциал использования генерации данных самой моделью в обучении LLM. Квантование LLM для выполнения инструкций: Было установлено, что методы квантования существенно влияют на производительность LLM, причем квантование больших моделей до меньших размеров (с использованием различных методов) может повысить их эффективность. Ключевое наблюдение – квантование моделей с большими параметрами (405B) часто дает лучшие результаты. Память в LLM: Было доказано, что LLM обладают памятью, а архитектура Transformer выполняет функцию аппроксимации входных данных, демонстрируя «память Шрёдингера», которая активируется входными данными. Logic-of-Thought для улучшения рассуждений LLM: Новый подход Logic-of-Thought (LoT) показал значительное улучшение производительности LLM на задачах логического рассуждения, в частности, на наборах данных ReClor, LogiQA и ProofWriter, что подтверждает эффективность использования логических структур для повышения производительности моделей. В совокупности, данные исследования подчеркивают важность адаптации существующих моделей LLM и внедрения новых подходов для их улучшения в задачах самокоррекции, квантования, памяти и логического рассуждения. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### All the Latest in the World of LLM Over the past month, there have been some very interesting and significant events in the world of Large Language Models (LLM). Major companies have released fresh versions of their models. First, Google launched two new models, Gemini: Gemini-1.5-Pro-002 and Gemini-1.5-Flash-002. Key Features: More than a 50% price reduction for the 1.5 Pro version Results are delivered twice as fast with three times lower latency The main focus has been on improving performance and speed and reducing costs for models intended for industrial-grade systems. Details here DataGemma Google also released the DataGemma model. It includes a series of finely-tuned Gemma 2 models that assist language models (LLM) in accessing numerical and statistical data. In particular, they offer a new approach called Retrieval Interleaved Generation (RIG), which reliably integrates public statistical data from Data Commons into LLM responses. RIG is a tool-based approach that can interleave statistical tokens with natural language questions suitable for retrieval from Data Commons. To achieve this capability, they fine-tune LLM on a dataset of instruction and answer pairs generated using Gemini 1.5. The RIG approach improves factuality from 5-7% to approximately 58%. Llama 3.2 Meta is not falling behind and has released Llama 3.2: a lightweight model for devices, computer vision (Llama Vision), and much more! Meta released 10 new models ranging from 1B (text only) to 90B multimodal (text + image). Brief Overview: Llama 3.2 Vision: multimodal (text + image to text) models sized 11B and 90B based on the text models Llama 3.1, trained on 6 billion text-image pairs. Llama 3.2 Edge: multilingual text models at 1B and 3B for efficient local deployment. All Llama 3.2 models support a context length of 128k tokens. Knowledge distillation and pruning were used from 8B/70B to train the 1B/3B models. Llama Guard 3.2: 2 new, improved guard models with multimodal support. The Llama 3.2 3B model is comparable to the Llama 3.1 8B in IFEval, indicating strong use cases for local RAG applications or agents. Multimodal models are restricted for individuals and companies within the European Union. Available and integrated into the Hugging Face ecosystem from Hub to Transformers and TGI. More details in the official announcement: https://go.fb.me/8ar7oz Download Llama 3.2 models: https://go.fb.me/7eiq2z Llama-3.2's capabilities in computer vision are expected to surpass those of GPT-4o-mini. Multimodal capabilities are becoming essential as we move towards the next phase of more autonomous systems. The Llama 3.2 models at 1B and 3B, which support context lengths of up to 128K tokens, also appear impressive and are useful for applications on edge devices and mobile platforms. The Llama Stack API seems to have received several enhancements, simplifying the development of agent applications. Now, there is a CLI for Llama, client code in languages like Python and Node, Docker containers, and several distribution options. OpenAI Academy Meanwhile, OpenAI has delighted us with the academy's opening. The academy aims to foster innovation by investing in developers and organizations using AI, starting with low—and middle-income countries. The OpenAI Academy program will provide: Training and technical support: Assistance from OpenAI experts for developers and targeted organizations using AI. API credits: Distribution of an initial $1 million in API credits to expand access to OpenAI models, allowing participants to create and deploy innovative applications. Community building: Formation of a global network of developers for collaboration, knowledge sharing, and collective innovation. Competitions and incubators: Partnerships with philanthropists to invest in organizations addressing critical issues in their communities. Currently, there are no details on participation. ### Все новое из мира Large Language Model За последний месяц произошло очень интересных и знаковых событий в мире Large Language Model (LLM). Так мировые гиганты выпустили свежие версии своих моделей. Начнем с того, что Google выпустил 2 новые модели Gemini: Gemini-1.5-Pro-002 и Gemini-1.5-Flash-002. Основные особенности: Снижение цены более чем на 50% для версии 1.5 Pro В 2 раза более быстрая выдача результатов и в 3 раза ниже задержка Главный акцент был сделан на улучшении производительности, скорости и снижении стоимости моделей для создания систем промышленного уровня. Детали тут DataGemma Так же Google выпустили модель DataGemma. Она включает серию тонко настроенных моделей Gemma 2, которые помогают языковым моделям (LLM) получать доступ к числовым и статистическим данным. В частности, они предлагают новый подход под названием Retrieval Interleaved Generation (RIG), который надежно включает публичные статистические данные из Data Commons в ответы LLM. RIG — это инструментальный подход, который может чередовать статистические токены с вопросами на естественном языке, подходящими для извлечения из Data Commons. Чтобы достичь этой возможности, они дообучают LLM на наборе данных инструкций и ответов, сгенерированных с помощью Gemini 1.5. Подход RIG улучшает фактологичность с 5-7% до примерно 58%. Llama 3.2 Meta не отстаёт и выпустила Llama 3.2: легкую модель для девайсов, для компьютерного зрения (Llama Vision) и многое другое! В целом Meta выпустила 10 новых моделей от 1B (только текст) до 90B мультимодальных (текст + изображение). Краткий обзор: Llama 3.2 Vision: мультимодальные (текст + изображение к тексту) модели размером 11B и 90B на основе текстовых моделей Llama 3.1, обученные на 6 миллиардах пар текст-изображение. Llama 3.2 Edge: многоязычные текстовые модели на 1B и 3B для эффективного локального развертывания. Все модели Llama 3.2 поддерживают контекст длиной 128k токенов. Использовалась дистилляция знаний и обрезка с 8B/70B для обучения моделей 1B/3B. Llama Guard 3.2: 2 новые улучшенные модели защиты с поддержкой мультимодальности. Модель Llama 3.2 3B сопоставима с Llama 3.1 8B по IFEval, что свидетельствует о сильных сценариях использования для локальных приложений RAG или агентов. Мультимодальные модели ограничены для физических лиц и компаний, находящихся в Европейском Союзе. Доступны и интегрированы в экосистему Hugging Face от Hub до Transformers и TGI. Подробнее в официальном анонсе: https://go.fb.me/8ar7oz Скачать модели Llama 3.2: https://go.fb.me/7eiq2z Возможности Llama-3.2 в области компьютерного зрения соответствуют должны превосходить GPT-4o-mini. Мультимодальные возможности становятся необходимостью, поскольку мы движемся к следующей фазе более автономных систем. Модели Llama 3.2 на 1B и 3B, поддерживающие контекст длиной до 128K токенов, также выглядят впечатляюще и делают их полезными для приложений на периферийных устройствах и мобильных платформах. API Llama Stack, по-видимому, получило несколько дополнений, что должно упростить разработку агентных приложений. Теперь есть CLI для Llama, клиентский код на языках, таких как Python и Node, контейнеры Docker и несколько вариантов дистрибуций. OpenAI Academy Ну, а OpenAI порадовала нас открытие академии, которая будет способствовать инновациям, инвестируя в разработчиков и организации, использующие ИИ, начиная с стран с низким и средним уровнем доходов. Программа OpenAI Academy будет предоставлять: Обучение и технические консультации: Поддержка от экспертов OpenAI для разработчиков и целенаправленных организаций, использующих ИИ. Кредиты API: Распределение первоначальных $1 млн в виде кредитов на API для расширения доступа к моделям OpenAI, что позволит участникам создавать и развертывать инновационные приложения. Создание сообществ: Формирование глобальной сети разработчиков для сотрудничества, обмена знаниями и коллективных инноваций. Конкурсы и инкубаторы: Партнерство с филантропами для инвестирования в организации, решающие критически важные задачи в своих сообществах. Пока подробностей по участию нет. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Key Trends in LLM Reasoning Development In these notes, I’d like to highlight the latest trends and research in reasoning and new prompting techniques that improve output. Simply put, reasoning is the process of multi-step thinking, where several consecutive steps of reflection are performed, with each step depending on the previous one. It may seem that Reasoning and Chain of Thought (CoT) are the same thing. They are related but represent different concepts. Reasoning is a general concept of thinking and making inferences. It encompasses any forms of reflection and conclusions. Chain of Thought is a specific technique used to improve reasoning by adding intermediate steps to help the model clearly express its thoughts and reach more accurate solutions. Chain-of-Thought or Not In a study on which types of tasks benefit the most from using chain-of-thought (CoT), after meta-analyzing over 100 papers, it was found that CoT provides significant performance advantages, especially for tasks related to math and logic. Another interesting result from the article is that CoT can be applied selectively, maintaining performance while reducing computational costs. Given the diversity of models and their capabilities, LLM routing might eventually become a standard feature. Although the article does not mention OpenAI's new o1 models, the authors emphasize the need to move from CoT-prompt-based approaches to more reliable, robust, and accurate intermediate computations in LLMs. It is unclear how applicable these findings are to o1 models regarding their capabilities. However, this will become clear as new research and experiments are published. I will share interesting results as they emerge. Diagram of Thought (DoT) The Diagram of Thought (DoT) enhances the reasoning capabilities of large language models (LLMs) through mathematical rigor. The DAT model represents iterative reasoning in LLMs as constructing a directed acyclic graph (DAG). It integrates proposals, critiques, refinement, and verification into a single DAG structure. This allows DoT to handle complex logical inferences that go beyond linear or tree-like approaches. No external intervention is used, but the model employs tokens with specific roles to generate detailed reasoning processes. Iteration of Thought (IoT) A paper proposes the Iteration of Thought (IoT) framework to improve answers and reasoning capabilities of large language models (LLMs) through adaptive reasoning pathways. It employs an inner-dialogue agent that acts as a guide and dynamically adjusts reasoning pathways, allowing adaptive exploration of cross-options and enhancing the accuracy of answers. The difference from CoT and ToT (both rigid processes) is that prompt generation in IoT is a dynamic process that allows adaptation. "IoT represents a viable paradigm for autonomously refining answers in LLMs, demonstrating significant improvements over CoT and thus providing more adaptive and effective reasoning systems with minimal human involvement." Chain-of-Thought Reasoning without Prompting A few months ago this paper proposed a decoding process to elicit CoT reasoning paths without intense prompt engineering. They find that CoT paths are frequently inherent, allowing a closer look at how to effectively unlock the LLMs' intrinsic reasoning abilities. Key Takeaways: Chain of Thought (CoT) – This technique significantly improves performance in tasks related to math and logic by adding intermediate reasoning steps. CoT can be applied selectively, allowing for computational efficiency. Diagram of Thought (DoT) introduces a new way to structure reasoning through directed acyclic graphs (DAGs). It allows models beyond linear or tree-like reasoning, covering more complex and rigorous logical inferences. Iteration of Thought (IoT) introduces a dynamic process of reasoning adjustment through an internal dialogue agent. Unlike the rigid processes of CoT and DoT, IoT adapts to intermediate results, allowing models to refine answers to complex questions more accurately. These techniques open new horizons for the development of LLMs, making them more flexible and accurate, especially in the area of complex multi-step reasoning. ### Основные тенденции в развитии рассуждений LLM В это заметки хотелось бы раскрыть последние тенденции и исследования в области ризонинга и новых техник промптинга улучшающих аутпут. По простому ризонинг это процесс многошаговых рассуждений, где выполняется несколько последовательных шагов размышлений и где каждый шаг зависит от предыдущего. Может показаться, что Reasoning и Chain of Thought (CoT) это одно и то же. Они связаны, но это разные концепции. Reasoning — это общее понятие рассуждения и умозаключений. Оно включает любые формы размышлений и выводов. Chain of Thought — это конкретная техника, используемая для улучшения reasoning путем добавления промежуточных шагов, чтобы помочь модели ясно выразить свои мысли и более точно прийти к решению задачи. Сhain-of-Thought или нет В исследовании того, какие типы задач больше всего выигрывают от использования chain-of-thought (CoT) после мета-анализа более 100 статей было установлено, что CoT даёт значительные преимущества в производительности в первую очередь для задач, связанных с математикой и логикой. Ещё один интересный результат в статье заключается в том, что CoT можно применять избирательно, сохраняя производительность и сокращая затраты на вычисления. Учитывая разнообразие моделей и их возможностей, в какой-то момент маршрутизация LLM может стать стандартной функцией. Хотя в статье не упоминаются новые модели OpenAI o1, авторы подчёркивают необходимость перехода от подходов, основанных на CoT-подсказках, к более надёжным, устойчивым и точным промежуточным вычислениям в LLM. Неизвестно, насколько эти выводы применимы к моделям o1 с точки зрения их возможностей. Однако это станет ясно по мере публикации новых исследований и экспериментов. Буду делиться интересными результатами по мере их появления. Diagram of Thought (DoT) Диаграмма мысли (Diagram of Thought, DoT) усиливает способности больших языковых моделей (LLM) к рассуждению через математическую строгость. Модель DAT представляет итеративное рассуждение в LLM как построение направленного ациклического графа (DAG). Она объединяет предложения, критику, уточнение и проверку в единую DAG-структуру. Это позволяет DoT охватывать сложные логические выводы, выходящие за рамки линейных или древовидных подходов. Внешнее вмешательство не используется, но модель применяет токены с конкретными ролями для генерации детализированных процессов рассуждения. Итерация мысли (Iteration of Thought, IoT) В работе предлагается структура Iteration of Thought (IoT) для улучшения ответов и способностей рассуждения больших языковых моделей (LLM) с помощью адаптивных путей рассуждений. Она использует агента внутреннего диалога, который действует как проводник и динамически корректирует пути рассуждения, что позволяет адаптивно исследовать перекрестные варианты и повышать точность ответов. Отличие от CoT и ToT (оба являются жёсткими процессами) заключается в том, что генерация подсказок в IoT — это динамический процесс, который позволяет адаптироваться. «IoT представляет собой жизнеспособную парадигму для автономного уточнения ответов в LLM, демонстрируя значительные улучшения по сравнению с CoT и тем самым обеспечивая более адаптивные и эффективные системы рассуждений с минимальным участием человека». Chain-of-Thought без промптинга Несколько месяцев назад в этой статье был предложен процесс декодирования для получения цепочек рассуждений CoT без интенсивного проектирования подсказок. Авторы выяснили, что цепочки рассуждений CoT часто являются неотъемлемой частью модели, что позволяет более внимательно рассмотреть, как эффективно раскрыть внутренние способности LLM к рассуждению. Вывод Эти исследования подчеркивают актуальные тенденции в области reasoning и разработки новых техник для улучшения рассуждений и промптинга в больших языковых моделях (LLM). Основные выводы: Chain of Thought (CoT) – это техника, которая значительно улучшает производительность в задачах, связанных с математикой и логикой, благодаря добавлению промежуточных шагов рассуждений. CoT может применяться избирательно, что позволяет сохранять вычислительную эффективность. Diagram of Thought (DoT) – предлагает новый способ структурирования рассуждений через направленные ациклические графы (DAG). Это позволяет моделям выходить за рамки линейных или древовидных рассуждений, охватывая более сложные и строгие логические выводы. Iteration of Thought (IoT) – внедряет динамический процесс корректировки рассуждений через агент внутреннего диалога. В отличие от жёстких процессов CoT и DoT, IoT адаптируется к промежуточным результатам, позволяя моделям точнее уточнять ответы на сложные вопросы. Эти техники открывают новые горизонты для развития LLM, делая их более гибкими и точными, особенно в области сложных многошаговых рассуждений. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Pandas for Data Science With this note, I am launching a series of articles for beginners in Data Science and Machine Learning. We’ll start by exploring Pandas. While there are many articles on Pandas available online, I want to focus on practical techniques for using Pandas in Data Science projects and model building. Dataset: We will use the German Credit Risk dataset from Kaggle. The dataset contains information on credit data: Age Sex Job Housing Saving accounts Checking account Credit amount Duration Purpose Working with Jupyter Notebook Before diving into Pandas for complete beginners, I’d like to discuss working in the Jupyter Notebook environment briefly. When you execute code in a Jupyter Notebook, the results are stored in memory. Even if you delete a cell, the data it created remains accessible until you restart the kernel. In Jupyter Notebook, there are two main types of cells: Code: Used for writing and executing Python code. Markdown: Used for formatting text, creating headers, lists, links, and other formatted text. Jupyter Notebook offers keyboard shortcuts to speed up your workflow. For example: Shift + Enter: Execute the current cell and move to the next one. Ctrl + Enter: Execute the current cell and stay in it. B: Add a new cell below the current one. A: Add a new cell above the current one. Python Basics for Pandas Now, let’s cover some useful Python principles and constructs for working with Pandas. Loops Loops in Python, such as for and while, allow you to perform the same operations multiple times. However, using loops in Pandas is often inefficient, especially for large datasets. Directly using loops in Pandas can significantly slow down code execution. For example, consider the task of lemmatizing text (reducing words to their base form): import nltk from nltk.stem import WordNetLemmatizer from nltk.tokenize import word_tokenize nltk.download('punkt') nltk.download('wordnet') nltk.download('omw-1.4') def lemmatize(text): lemmatizer = WordNetLemmatizer() tokens = word_tokenize(text) lemmatized_tokens = [lemmatizer.lemmatize(token) for token in tokens] return ' '.join(lemmatized_tokens) lemmas = [] for text in data['Purpose']: lemmas.append(lemmatize(text)) data['Lemmatized'] = lemmas Now, the same example using the apply() method: data['Lemmatized'] = data['Purpose'].apply(lemmatize) Using apply() works faster and requires less code since Pandas optimizes the execution of internal operations. Functions Functions in Python are key tools for reusing code. They allow you to break down code into smaller parts, each performing a specific task. def Is used to define named functions, which can contain multiple statements and perform complex operations. Suppose we need to convert clients' ages (column Age) into age groups: def age_group(age): if age < 30: return 'Young' elif 30 <= age < 60: return 'Middle-aged' else: return 'Senior' data['Age Group'] = data['Age'].apply(age_group) lambda is used to create anonymous functions, which usually contain a single expression. For example, suppose we need to add 10% to each value in the Credit amount column: data['Adjusted Credit Amount'] = data['Credit amount'].apply(lambda x: x * 1.1) def предпочтительнее использовать, когда функция сложна или требует документирования, а lambda полезен для простых одноразовых задач. try-except The try-except block helps prevent errors from interrupting program execution. Suppose we try to convert the values in the Credit amount column to integers, but some values might be incorrect (e.g., strings). We use try-except to handle possible errors: def safe_convert_to_int(value): try: return int(value) except ValueError: return None data['Credit amount (int)'] = data['Credit amount'].apply(safe_convert_to_int) In this example, the safe_convert_to_int() function tries to convert a value to an integer. If an error occurs (e.g., if the value is not a number), try-except catches the error, and the function returns None. Pandas for Data Science And finally, we have arrived at Pandas. Let's quickly go over the basics. Pandas allows you to load data from files with various delimiters (field separators). By default, pd.read_csv() it assumes that the delimiter is a comma. If the data is separated by other characters, such as semicolons, tabs, or spaces, you need to specify this when loading the file explicitly: df_semicolon = pd.read_csv('data_semicolon.csv', sep=';') df_tab = pd.read_csv('data_tab.csv', sep='\\t') df_space = pd.read_csv('data_space.csv', sep=' ') File encoding is crucial, especially when dealing with data containing special characters or text in other languages. If the file is not encoded in UTF-8, you need to specify its encoding: df_iso = pd.read_csv('data_iso.csv', encoding='ISO-8859-1') df_utf16 = pd.read_csv('data_utf16.csv', encoding='utf-16') Data Overview Functions After loading the data, it's important to understand its structure and quality quickly. Pandas provides several useful functions for this: .info() provides a summary of the DataFrame: the number of records, number of columns, their names, data types, and the number of non-null values. .describe() outputs statistical summaries of the numeric columns: mean, standard deviation, minimum and maximum values, quartile values. .head() shows the first 5 rows of the DataFrame. You can specify the number of rows to display. .tail() shows the last 5 rows of the DataFrame. .sample() selects random rows from the DataFrame, useful for a quick data overview. .shape() returns the dimensions of the DataFrame, i.e., the number of rows and columns. Data Types Casting data types in Pandas is important for several reasons: Memory Optimization: Some data types take up less memory. For example, casting columns with text values to the category type significantly reduces the memory usage compared to the object type. Faster Computation: Working with numeric data types (e.g., int, float) is faster and more efficient than with the object type. This is especially important for large datasets. Correctness of Operations: Type casting helps avoid errors when performing operations on data. For example, comparison or arithmetic operations might not work correctly if the data type is incorrect. Binary variables are those that can only take two values, such as 0 and 1, True and False, or other equivalents (e.g., Yes and No): data['Is Male'] = data['Sex'].apply(lambda x: 1 if x == 'male' else 0) In this example, a new column Is Male is created, which contains 1 if the customer is male, and 0 if female. Binary variables are often used in modeling to indicate the presence or absence of a feature. The category data type has several advantages over object: Data Understanding: Casting to category helps explicitly indicate categorical features, which is important for analysis and modeling. Reduced Memory Usage: If a column has a small number of unique values, the category type stores these values as categories rather than strings, reducing memory usage. Faster Operations: Comparison, sorting, and grouping operations are faster with the category type due to its optimized internal data representation. data['Sex'] = data['Sex'].astype('category') int and float Data Types The int and float data types differ as follows: int (integers): Used to represent whole numbers with no fractional part. Takes up less memory than float. float (floating-point numbers): Used to represent numbers with a fractional part. Takes up more memory and may be less accurate due to how floating-point numbers are stored. When to use int and float? Use int if the data will always be whole numbers (e.g., the number of items, age). Use float if fractional values are possible (e.g., prices, percentages). The pd.to_numeric() method is used to cast data to numeric types (e.g., int or float). This is useful if the data contains strings that can be converted to numbers. data['Credit amount'] = pd.to_numeric(data['Credit amount'], errors='coerce') If there is a value in the column that cannot be converted to a number, the method will replace it with NaN (if the errors='coerce' parameter is used). This helps to avoid errors during analysis and calculation. Accessing Columns In Pandas, you can access DataFrame columns in two main ways: via dot notation (.) and square brackets ([]). Both methods have their own features and limitations. It doesn't work if the column name matches a method or attribute of the DataFrame. Dot Notation: This method is convenient and compact, but it has some limitations: It only works for columns whose names do not contain spaces or special characters. data.Age Here, data.Age returns the Age column as a Series. Square Brackets: This is a more universal method as column names do not limit it: It supports accessing columns with any names, including those containing spaces, special characters, or matching DataFrame methods/attributes. You can use it to access multiple columns at once (a list of columns is passed). Examples: # Accessing a single column data['Age'] # Accessing a column with a name containing a space data['Saving accounts'] # Accessing multiple columns data[['Age', 'Credit amount']] Indexing Pandas offers several methods for indexing and selecting data from a DataFrame: iloc is used for selecting data by their positions (numeric indexes). It works for both rows and columns. Examples: # Selecting the first row (indexing starts from 0) data.iloc[0] # Selecting the first five rows data.iloc[:5] # Selecting the value in the first row and second column data.iloc[0, 1] # Selecting the first three rows and the first two columns data.iloc[:3, :2] loc Is used to select data by labels (names of rows and columns). Examples: # Selecting the row with index 0 data.loc[0] # Selecting all rows where the value in the 'Age' column equals 30 data.loc[data['Age'] == 30] # Selecting the value in the row with index 0 and the 'Age' column data.loc[0, 'Age'] # Selecting the first three rows and the 'Age' and 'Credit amount' columns data.loc[:2, ['Age', 'Credit amount']] When using [] to access rows (like data[0:5]), Pandas returns rows with numbers from 0 to 4 (selection by row index). When accessing a column (like data['Age']), the specified column is returned. Examples: # Selecting the first five rows data[0:5] # Selecting the 'Age' column data['Age'] Data Filtering Data filtering allows you to select rows that meet certain conditions. The .drop() method is used to delete rows or columns. You can specify the axis for deletion (axis=0 for rows, axis=1 for columns). Examples: # Deleting the 'Age' column data.drop('Age', axis=1) # Deleting rows with indexes 0, 1, and 2 data.drop([0, 1, 2], axis=0) The .query() method allows you to filter rows based on logical conditions written as a string. Example: # Selecting all rows where 'Age' is greater than 30 and 'Credit amount' is less than 5000 data.query('Age > 30 & `Credit amount` < 5000') You can use .loc[] to filter rows based on a condition: Example: # Selecting all rows where 'Age' is greater than 30 data.loc[data['Age'] > 30] In Pandas, most methods, like .drop(), .fillna(), .replace() Have an inplace parameter, which, if set to True, modifies the original DataFrame directly instead of creating a copy. Example of using inplace: # Deleting a column using inplace data.drop('Age', axis=1, inplace=True) Dangers of inplace: Loss of Flexibility: Without inplace, you can keep both the original data and the new data, allowing you to compare the results or revert to the original data if something goes wrong. Irreversibility of Changes: When using inplace=True, changes to the DataFrame are made in place, and if you accidentally delete or modify data, it cannot be easily undone. Problems with Method Chaining: If you use multiple methods in a chain, inplace=True can cause errors or unexpected behavior, as the modified DataFrame may no longer meet the expected conditions. Grouping and Sorting Data The .agg() method is used to perform various aggregate functions on data grouped by one or more columns. You can apply multiple aggregate functions to several columns simultaneously. Example of using .agg(): # Grouping data by the 'Sex' column and aggregating using multiple metrics aggregated_data = data.groupby('Sex').agg({ 'Age': ['mean', 'min', 'max'], # Calculate mean, minimum, and maximum for the 'Age' column 'Credit amount': ['sum', 'mean'] # Calculate sum and mean for the 'Credit amount' column }) As a result, you'll get a DataFrame where the specified aggregate functions are calculated for each group (Sex) for the corresponding columns. The .sort_values() method allows you to sort data by multiple columns at once, with the option to specify the sorting order for each column. Example: # Sorting data by 'Age' in ascending order and 'Credit amount' in descending order sorted_data = data.sort_values(by=['Age', 'Credit amount'], ascending=[True, False]) Here, the rows will be sorted first by ascending age and then by descending credit amount. Categorization The .map() method allows you to replace values in a column based on a provided mapping (dictionary) or function. Examples: # Replacing values in the 'Sex' column with numerical values data['Sex'] = data['Sex'].map({'male': 1, 'female': 0}) # Transforming values in the 'Age' column using a function data['Age group'] = data['Age'].map(lambda x: 'young' if x < 30 else 'adult') The .cut() method divides numerical data into intervals, creating a new categorical variable. Example: # Dividing age into three groups data['Age group'] = pd.cut(data['Age'], bins=[0, 30, 50, 100], labels=['young', 'middle-aged', 'senior']) Here, age is divided into three categories: young (0 to 30 years), middle-aged (30 to 50 years), and senior (50 to 100 years). Categorization by String Matching Sometimes, you need to create a new category based on the presence of a specific word in a string. This can be done using Pandas methods. Example: # Creating a new column that indicates whether the 'Purpose' column contains the word 'car' data['Car related'] = data['Purpose'].apply(lambda x: 'car' in x.lower()) In this example, the Car related column will have True if the word "car" appears in the Purpose column, and False otherwise. Conditional Data Replacement The np.where() function allows you to replace values based on a condition. Example: import numpy as np # Replacing values in the 'Age' column with 'young' if age is less than 30, otherwise 'adult' data['Age category'] = np.where(data['Age'] < 30, 'young', 'adult') The np.select() function allows you to set multiple conditions for replacing values. Example: conditions = [ (data['Age'] < 30), (data['Age'] >= 30) & (data['Age'] < 50), (data['Age'] >= 50) ] choices = ['young', 'middle-aged', 'senior'] # Assigning values based on which condition is met data['Age group'] = np.select(conditions, choices, default='unknown') Here, np.select() checks the conditions and replaces values in the Age group column based on which condition is met. You can use a standard if-else expression within a function and apply it to the data using the .apply() method. Example: # Defining a function def age_category(age): if age < 30: return 'young' elif age < 50: return 'middle-aged' else: return 'senior' # Applying the function to the 'Age' column data['Age group'] = data['Age'].apply(age_category) The pd.where() method leaves values unchanged if a condition is met and replaces them if the condition is not met. Example: # Replacing all values in the 'Age' column where age is greater than 30 with '30+' data['Age'] = data['Age'].where(data['Age'] > 30, '30+') Here, all values in the Age column where age is greater than 30 will be replaced with the string '30+', while other values will remain unchanged. Dealing with Bad Data When analyzing data, situations often arise where certain values are anomalous or erroneous. In a study conducted using a nested dataset, it was found that the average work experience of two categories of clients significantly exceeded normal values. This raised a valid question: how can these data be correctly processed to improve the quality of analysis and make the results more reliable? Causes of Data Anomalies: Data Entry Errors: Mistakes during data entry may result in incorrect values. For example, 50 years of work experience might have been recorded instead of 5 years. Validation Rule Violations: If the data collection system lacks adequate checks, incorrect values may appear in the final dataset. Rare Events: An anomaly may reflect a real but rare situation. For instance, some clients may have a long work experience, though there are few cases. System Failures: System errors during data collection can lead to incorrect values. Approaches to Handling Anomalous or Erroneous Data: Removing Anomalous Values: If a value is clearly incorrect and cannot be corrected, it can be removed from the dataset. However, this method may lead to loss of important information. Replacing Values with Mean or Median: If anomalous values significantly distort the overall picture, they can be replaced with the mean or median values for the relevant category. Using Machine Learning Methods: Some algorithms can automatically detect and handle anomalies, leaving only meaningful data for analysis. Correcting Values Based on Business Rules: For example, if it's known that the maximum work experience in an industry does not exceed 40 years, all values exceeding this limit can be replaced with 40. Practical Application: In practice, combined methods are often used. First, a detailed analysis of anomalous data is conducted to investigate possible causes and their impact on the final result. Depending on the context, a decision is made on removing, correcting, or retaining such data. If the anomaly is linked to a real but rare situation, it may be kept in the data but flagged as an exception. The data are corrected or removed if the anomaly is due to an input error or system failure. Example of Identifying and Handling Anomalous Values: Anomalous values can be identified using descriptive statistics. For example, values that exceed 3 standard deviations from the mean can be considered anomalous. import numpy as np # Calculating the mean and standard deviation mean_duration = data['Duration'].mean() std_duration = data['Duration'].std() # Defining boundaries for anomalous values upper_bound = mean_duration + 3 * std_duration lower_bound = mean_duration - 3 * std_duration # Filtering anomalous values anomalies = data[(data['Duration'] > upper_bound) | (data['Duration'] < lower_bound)] After identifying anomalies, they can be handled in various ways, such as replacing them with the median value. # Replacing anomalous values with the median value median_duration = data['Duration'].median() data['Duration'] = np.where((data['Duration'] > upper_bound) | (data['Duration'] < lower_bound), median_duration, data['Duration']) Handling Missing Data Missing data can occur for various reasons: errors during data collection, lack of information, or technical failures. It is important to consider that missing values can significantly impact analysis results, so they must be handled correctly. Missing values should be replaced if: They are significant in number: If there are many missing values in a column, ignoring them might skew the analysis. They are in key variables: If the missing values are in variables critical to the analysis, they should be replaced to maintain data integrity. The data is needed for further modeling. In machine learning, complete data is often necessary, so missing values must be filled. Methods for Replacing Missing Values depend on the data type and context: Replacing with Mean or Median: Used for numerical data if the data distribution is symmetric or has outliers. Replacing with Mode (Most Frequent Value): Suitable for categorical data. Replacing Based on Data from Other Columns: If salary data is missing, the position could be filled based on the job title listed in another column. Using Models to Predict Missing Values: A more complex method where missing values are filled using predictive models. Pandas Commands for Replacing Missing Values: data.fillna(value) # Replaces all missing values in the DataFrame with the specified value. data['column'].fillna(data['column'].mean(), inplace=True) # Replaces missing values in a specific column with the mean. data['column'].fillna(data['column'].median(), inplace=True) # Replaces missing values with the median. data.fillna(method='ffill') # Fills missing values with the previous value. data.fillna(method='bfill') # Fills missing values with the next value. missing_values = data.isnull().sum() print(missing_values) After running the code, we see that the "Saving accounts" and "Checking account" columns are missing values. Let's explore different approaches to handling the missing values in the "Checking account" column. Replacing with the Most Frequent Value (Mode): If one category is more common than others, the missing values can be replaced with it. # Replacing missing values with the most frequent value most_frequent = data['Checking account'].mode()[0] data['Checking account'].fillna(most_frequent, inplace=True) Replacing with a Special Value: Missing values can be replaced with a specific value, such as "Unknown" or "No account," if that makes sense in the data context. # Replacing missing values with 'Unknown' data['Checking account'].fillna('Unknown', inplace=True) Replacing Based on Data from Other Columns: If there are other columns in the dataset that may correlate with the presence or type of account, these data can be used to fill the missing values. data['Checking account'] = data.groupby('Job')['Checking account'].transform(lambda x: x.fillna(x.mode()[0] if not x.mode().empty else 'Unknown')) Handling Duplicates in Data Duplicates in data are records that are entirely or partially repeated. The presence of duplicates can distort the results of analysis, so it is important to identify and remove them in a timely manner. In Pandas, the duplicated() method is used to find duplicates. It returns a boolean array (True or False) for each row, indicating whether that row is a duplicate. data.duplicated(keep=False) — marks all rows as duplicates, including both the first and last occurrences. data.duplicated() — returns True for all rows that are duplicated (including the first occurrence). data.duplicated(keep='first') — marks all rows as duplicates except for the first occurrence. data.duplicated(keep='last') — marks all rows as duplicates except for the last occurrence. duplicates = data[data.duplicated()] print(f'Number of duplicates: {duplicates.shape[0]}') # Viewing duplicates print(duplicates) After identifying duplicates, you can choose from several methods to handle them: Removing Duplicates: If duplicates do not contain unique information, they can be removed. # Removing all duplicates, keeping the first occurrence data = data.drop_duplicates(keep='first') # Checking the number of rows after removing duplicates print(f'Number of rows after removing duplicates: {data.shape[0]}') Aggregating Data: If duplicates have different values in some fields, they can be combined, for example, by taking the mean or sum. # Example of aggregation (taking the mean for numerical columns) df_aggregated = data.groupby(data.columns.tolist(), as_index=False).mean() Marking and Further Analysis: In some cases, duplicates can be retained but flagged for consideration in further analysis. # Adding a flag for duplicates data['is_duplicate'] = data.duplicated(keep=False) Duplicates can occur for various reasons: Lack of Unique Identifiers: If the data lacks unique identifiers (e.g., customer IDs), the system may not recognize records as unique, even if they represent different people or events. Data Collection Errors: For example, if the same client was entered into the system twice by mistake. Merging Multiple Data Sources: The same records may appear multiple times when combining data from different sources. Repeated Data Loading: Sometimes, data may be loaded again, resulting in duplicates. Conclusion In this note, I aimed to cover various use cases of Pandas in Data Science projects, providing practical techniques and examples. All of this will be useful in upcoming articles in the series designed for beginners entering the fields of Data Science and Machine Learning. ### Pandas для Data Science Этой заметкой открываю серию статей для начинающих вкатываться в Data Sciеnce и Machine Learning и начнем мы с изучения Pandas. В интернете много статей по Pandas, поэтому хотел бы в этой заметки описать практические приемы для работы с Pandas в Data Sciеnce проектах и для построения моделей. В качестве датасета будем использовать German Credit Risk на Kaggle Датасет содержит информацию о кредитных данных: Age (возраст) Sex (пол) Job (работа) Housing (тип жилья) Saving accounts (сберегательные счета) Checking account (расчетный счет) Credit amount (сумма кредита) Duration (продолжительность кредита) Purpose (цель кредита) Работа с Jupyter Notebook Прежде чем мы перейдем к Pandas для совсем новичков хочу немного рассказать о работе в среде Jupyter Notebook. Когда вы выполняете код в Jupyter Notebook, результаты вычислений сохраняются в оперативной памяти. Даже если вы удалите ячейку, данные, созданные ею, останутся доступны до тех пор, пока вы не перезапустите ядро (kernel). В Jupyter Notebook существуют два основных типа ячеек: Код: используется для написания и выполнения Python кода. Markdown: используется для оформления текста, создания заголовков, списков, ссылок и другого форматированного текста. Jupyter Notebook предоставляет горячие клавиши, которые ускоряют работу. Например: Shift + Enter: выполнить текущую ячейку и перейти к следующей. Ctrl + Enter: выполнить текущую ячейку и остаться в ней. B: добавить новую ячейку под текущей. A: добавить новую ячейку над текущей. Основы Python для Pandas А теперь расскажу некоторые принципы и конструкции Python полезные в работе с Pandas. Циклы Циклы в Python, такие как for и while, позволяют выполнять одни и те же операции несколько раз. При работе с библиотекой Pandas, использование циклов часто бывает неэффективным, особенно для больших наборов данных. Прямое использование циклов в Pandas может существенно замедлить выполнение кода. Например, рассмотрим задачу лемматизации текста (приведение слов к их начальной форме): import nltk from nltk.stem import WordNetLemmatizer from nltk.tokenize import word_tokenize nltk.download('punkt') nltk.download('wordnet') nltk.download('omw-1.4') def lemmatize(text): lemmatizer = WordNetLemmatizer() tokens = word_tokenize(text) lemmatized_tokens = [lemmatizer.lemmatize(token) for token in tokens] return ' '.join(lemmatized_tokens) lemmas = [] for text in data['Purpose']: lemmas.append(lemmatize(text)) data['Lemmatized'] = lemmas Теперь тот же пример с использованием метода apply(): data['Lemmatized'] = data['Purpose'].apply(lemmatize) Использование apply() работает быстрее и требует меньше кода, поскольку Pandas оптимизирует выполнение внутренних операций. Функции Функции в Python — это основной инструмент для повторного использования кода. Они позволяют разбивать код на более мелкие части, каждая из которых выполняет одну конкретную задачу. def используется для определения именованных функций, которые могут содержать несколько операторов и выполнять сложные операции. Предположим, что у нас есть задача преобразовать возраст клиентов (колонка Age) в группы по возрасту: def age_group(age): if age < 30: return 'Young' elif 30 <= age < 60: return 'Middle-aged' else: return 'Senior' data['Age Group'] = data['Age'].apply(age_group) lambda используется для создания анонимных функций, которые обычно содержат одно выражение. Например, предположим, что нам нужно добавить к каждому значению в колонке Credit amount 10%: data['Adjusted Credit Amount'] = data['Credit amount'].apply(lambda x: x * 1.1) def предпочтительнее использовать, когда функция сложна или требует документирования, а lambda полезен для простых одноразовых задач. try-except Конструкция try-except помогает избежать ошибок, которые могут прервать выполнение программы. Допустим, мы пытаемся преобразовать значения в колонке Credit amount в целые числа, но некоторые значения могут быть некорректными (например, строки). Используем try-except, чтобы обрабатывать возможные ошибки: def safe_convert_to_int(value): try: return int(value) except ValueError: return None data['Credit amount (int)'] = data['Credit amount'].apply(safe_convert_to_int) В этом примере функция safe_convert_to_int() пытается преобразовать значение в целое число. Если возникает ошибка (например, если значение не является числом), try-except перехватывает ошибку, и функция возвращает None. Pandas для Data Science И вот мы наконец-то дошли до Pandas. Быстро пробежим по основам. Pandas позволяет загружать данные из файлов с различными разделителями (разделителями полей). По умолчанию, pd.read_csv() предполагает, что разделителем является запятая. Если данные разделены другими символами, например, точкой с запятой, табуляцией или пробелом, нужно явно указать это при загрузке файла: df_semicolon = pd.read_csv('data_semicolon.csv', sep=';') df_tab = pd.read_csv('data_tab.csv', sep='\\t') df_space = pd.read_csv('data_space.csv', sep=' ') Кодировка файлов важна, особенно при работе с данными, содержащими специальные символы или текст на других языках. Если файл закодирован не в UTF-8, нужно указать его кодировку: df_iso = pd.read_csv('data_iso.csv', encoding='ISO-8859-1') df_utf16 = pd.read_csv('data_utf16.csv', encoding='utf-16') Функции обзора данных После загрузки данных важно быстро понять их структуру и качество. Pandas предоставляет несколько полезных функций для этого. .info() выводит краткую информацию о DataFrame: количество записей, количество столбцов, их имена, типы данных и количество ненулевых значений. .describe() выводит статистические сводки по числовым столбцам: среднее значение, стандартное отклонение, минимальное и максимальное значение, квартильные значения. .head() показывает первые 5 строк DataFrame. Можно указать конкретное количество строк для отображения. .tail() показывает последние 5 строк DataFrame. .sample() выбирает случайные строки из DataFrame, что полезно для беглого обзора данных. .shape() возвращает размерность DataFrame, т.е. количество строк и столбцов. Типы данных Приведение типов данных в Pandas имеет важное значение по нескольким причинам: Оптимизация памяти: Некоторые типы данных занимают меньше памяти. Например, приведение столбцов с текстовыми значениями к типу category значительно снижает объем занимаемой памяти по сравнению с типом object. Ускорение вычислений: Работа с числовыми типами данных (например, int, float) быстрее и эффективнее, чем с типом object. Это особенно важно для больших наборов данных. Корректность операций: Приведение типов помогает избежать ошибок при выполнении операций над данными. Например, операции сравнения или арифметические операции могут работать некорректно, если данные имеют неправильный тип. Бинарные переменные — это переменные, которые могут принимать только два значения, например, 0 и 1, True и False, или другие эквиваленты (например, Да и Нет): data['Is Male'] = data['Sex'].apply(lambda x: 1 if x == 'male' else 0) В этом примере создается новая колонка Is Male, которая содержит 1, если пол клиента — мужской, и 0 — если женский. Бинарные переменные часто используются в моделировании для обозначения наличия или отсутствия какого-либо признака. Тип данных category имеет ряд преимуществ по сравнению с object: Меньшее использование памяти: Если столбец имеет небольшое количество уникальных значений, тип category хранит эти значения как категории, а не строки, что снижает использование памяти. Ускорение операций: Операции по сравнению, сортировке и группировке выполняются быстрее с типом category из-за оптимизированного внутреннего представления данных. Понимание данных: Приведение к category помогает явно обозначить категориальные признаки, что важно для анализа и моделирования. data['Sex'] = data['Sex'].astype('category') Типы данных int и float различаются следующим: int (целые числа): Используется для представления целых чисел, которые не имеют дробной части. Занимает меньше памяти, чем float. float (вещественные числа): Используется для представления чисел с дробной частью. Занимает больше памяти и может быть менее точным из-за особенностей хранения чисел с плавающей запятой. Когда использовать int и float? Используйте int, если данные всегда будут целыми числами (например, количество товаров, возраст). Используйте float, если возможны дробные значения (например, цены, проценты). Подробнее о разнице можно почитать по ссылке. Метод pd.to_numeric() используется для приведения данных к числовому типу (например, int или float). Это полезно, если данные содержат строки, которые могут быть преобразованы в числа. data['Credit amount'] = pd.to_numeric(data['Credit amount'], errors='coerce') Если в колонке окажется значение, которое невозможно преобразовать в число, метод заменит его на NaN (если использовать параметр errors='coerce'). Это помогает избежать ошибок при анализе и расчете. Обращение к колонкам В Pandas можно обращаться к колонкам DataFrame двумя основными способами: через точку (.) и через квадратные скобки ([]). Оба метода имеют свои особенности и ограничения. Обращение через точку (.) - этот способ удобен и компактен, но он имеет ряд ограничений: Работает только для колонок, имена которых не содержат пробелов и специальных символов. Не работает, если имя колонки совпадает с именем метода или атрибута DataFrame. data.Age Здесь data.Age возвращает колонку Age как Series. Обращение через квадратные скобки ([]) - это более универсальный способ, так как он не ограничен именами колонок: Поддерживает обращение к колонкам с любыми именами, включая те, которые содержат пробелы, специальные символы, или совпадают с методами/атрибутами DataFrame. Можно использовать для обращения к нескольким колонкам сразу (передается список колонок). Примеры: # Обращение к одной колонке data['Age'] # Обращение к колонке с именем, содержащим пробел data['Saving accounts'] # Обращение к нескольким колонкам data[['Age', 'Credit amount']] Индексация Pandas предлагает несколько способов для индексации и выборки данных из DataFrame: iloc используется для выборки данных по их позициям (числовым индексам). Работает как для строк, так и для колонок. Примеры: # Выбор первой строки (индексация начинается с 0) data.iloc[0] # Выбор первых пяти строк data.iloc[:5] # Выбор значения в первой строке и втором столбце data.iloc[0, 1] # Выбор первых трех строк и первых двух столбцов data.iloc[:3, :2] loc используется для выборки данных по меткам (названиям строк и колонок). Примеры: # Выбор строки с индексом 0 data.loc[0] # Выбор всех строк, где значение в колонке 'Age' равно 30 data.loc[data['Age'] == 30] # Выбор значения в строке с индексом 0 и колонке 'Age' data.loc[0, 'Age'] # Выбор первых трех строк и колонок 'Age' и 'Credit amount' data.loc[:2, ['Age', 'Credit amount']] Когда используете [] для обращения к строкам (как data[0:5]), Pandas возвращает строки с номерами от 0 до 4 (выбор по индексу строк). А при обращении к колонке (как data['Age']), возвращается указанная колонка. Примеры: # Выбор первых пяти строк data[0:5] # Выбор колонки 'Age' data['Age'] Фильтрация данных Фильтрация данных позволяет выбрать строки, соответствующие определенным условиям. Метод .drop() используется для удаления строк или колонок. Вы можете указать ось (axis) для удаления (0 — строки, 1 — колонки). Примеры: # Удаление колонки 'Age' data.drop('Age', axis=1) # Удаление строк с индексами 0, 1 и 2 data.drop([0, 1, 2], axis=0) Метод .query() позволяет фильтровать строки на основе логических условий, написанных как строка. Пример: # Выбор всех строк, где 'Age' больше 30 и 'Credit amount' меньше 5000 data.query('Age > 30 & `Credit amount` < 5000') Вы можете использовать .loc[] для фильтрации строк, основанной на условии: Пример: # Выбор всех строк, где 'Age' больше 30 data.loc[data['Age'] > 30] В Pandas большинство методов, таких как .drop(), .fillna(), .replace(), имеют параметр inplace, который, если установлен в True, модифицирует исходный DataFrame напрямую, а не создает его копию. Пример использования inplace: # Удаление колонки с использованием inplace data.drop('Age', axis=1, inplace=True) Опасности: Необратимость изменений: При использовании inplace=True, изменения в DataFrame выполняются на месте, и если вы случайно удалите или измените данные, это не может быть легко отменено. Проблемы с цепочкой методов: Если вы используете несколько методов в цепочке, inplace=True может вызвать ошибки или нежелательное поведение, так как измененный DataFrame может больше не соответствовать ожидаемым условиям. Потеря гибкости: Без inplace вы можете сохранить исходные данные и новые данные, чтобы иметь возможность сравнить результаты или вернуться к исходным данным, если что-то пойдет не так. Группировка и сортировка данных Метод .agg() используется для выполнения различных агрегатных функций над данными, сгруппированными по одному или нескольким столбцам. Вы можете применять несколько агрегатных функций к нескольким колонкам одновременно. Пример использования .agg(): # Группировка данных по колонке 'Sex' и агрегация по нескольким метрикам aggregated_data = data.groupby('Sex').agg({ 'Age': ['mean', 'min', 'max'], # Для колонки 'Age' вычисляем среднее, минимум и максимум 'Credit amount': ['sum', 'mean'] # Для колонки 'Credit amount' вычисляем сумму и среднее }) В результате вы получите DataFrame, где для каждой группы (Sex) будут рассчитаны указанные агрегатные функции для соответствующих колонок. Метод .sort_values() позволяет сортировать данные по нескольким колонкам одновременно, причем для каждой колонки можно задать свой порядок сортировки. Пример: # Сортировка данных по 'Age' по возрастанию и 'Credit amount' по убыванию sorted_data = data.sort_values(by=['Age', 'Credit amount'], ascending=[True, False]) Здесь строки будут отсортированы сначала по возрастанию возраста, а затем по убыванию суммы кредита. Разбивка на категории Метод .map() позволяет заменить значения в колонке на основе переданного отображения (словаря) или функции. Примеры: # Замена значений в колонке 'Sex' на числовые значения data['Sex'] = data['Sex'].map({'male': 1, 'female': 0}) # Преобразование значений колонки 'Age' с использованием функции data['Age group'] = data['Age'].map(lambda x: 'young' if x < 30 else 'adult') Метод .cut() используется для разбиения числовых данных на интервалы, создавая новую категориальную переменную. Пример: # Разбивка возраста на три группы data['Age group'] = pd.cut(data['Age'], bins=[0, 30, 50, 100], labels=['young', 'middle-aged', 'senior']) Здесь возраст будет разбит на три категории: young (от 0 до 30 лет), middle-aged (от 30 до 50 лет) и senior (от 50 до 100 лет). Категоризация по вхождению строки Иногда требуется создать новую категорию на основе наличия определенного слова в строке. Это можно сделать с помощью методов Pandas. Пример: # Создание новой колонки, которая показывает, содержит ли колонка 'Purpose' слово 'car' data['Car related'] = data['Purpose'].apply(lambda x: 'car' in x.lower()) В этом примере в колонке Car related будут значения True, если в колонке Purpose встречается слово "car", и False в противном случае. Замена данных по условию Функция np.where() позволяет заменять значения в зависимости от выполнения условия. Пример: import numpy as np # Замена значений в колонке 'Age' на 'young' если возраст меньше 30, иначе на 'adult' data['Age category'] = np.where(data['Age'] < 30, 'young', 'adult') Функция np.select() позволяет задавать несколько условий для замены значений. Пример: conditions = [ (data['Age'] < 30), (data['Age'] >= 30) & (data['Age'] < 50), (data['Age'] >= 50) ] choices = ['young', 'middle-aged', 'senior'] # Присваиваем значения в зависимости от выполнения условий data['Age group'] = np.select(conditions, choices, default='unknown') Здесь np.select() проверяет условия и заменяет значения в колонке Age group в зависимости от того, какое условие выполняется. Вы можете использовать стандартное выражение if-else внутри функции и применять его к данным с помощью метода .apply(). Пример: # Определяем функцию def age_category(age): if age < 30: return 'young' elif age < 50: return 'middle-aged' else: return 'senior' # Применяем функцию к колонке 'Age' data['Age group'] = data['Age'].apply(age_category) Метод pd.where() оставляет значения без изменений, если условие выполняется, и заменяет их, если не выполняется. Пример: # Замена всех значений в колонке 'Age', где возраст больше 30, на '30+' data['Age'] = data['Age'].where(data['Age'] > 30, '30+') Здесь все значения в колонке Age, где возраст больше 30, будут заменены на строку '30+', а остальные значения останутся без изменений. Плохие данные При анализе данных часто возникают ситуации, когда определенные значения выделяются из общей массы, являясь аномальными или ошибочными. В рамках исследования, проведенного с использованием вложенного датасета, было обнаружено, что средний стаж работы двух категорий клиентов значительно превышает нормальные значения. Это вызвало обоснованный вопрос: как можно корректно обработать эти данные, чтобы улучшить качество анализа и сделать его результаты более достоверными? Аномалии в данных могут возникать по разным причинам: Ошибки ввода данных: Возможно, при вводе данных в систему произошла ошибка, и значения были записаны неверно. Например, вместо 5 лет стажа могли указать 50. Нарушение правил валидации: Если система, которая собирает данные, не имеет достаточных проверок, некорректные значения могут попасть в итоговый датасет. Редкие события: Аномалия может отражать реальную, но редкую ситуацию. Например, возможно, что некоторые клиенты действительно обладают большим стажем, но таких случаев мало. Системные сбои: В процессе сбора данных могут произойти сбои, приводящие к появлению некорректных значений. Существует несколько подходов к обработке аномальных или ошибочных данных: Удаление аномальных значений: Если значение явно неверное и не поддается исправлению, его можно просто удалить из датасета. Однако, этот метод может привести к потере важной информации. Замена значений на среднее или медианное: Если аномальные значения сильно искажают общую картину, их можно заменить на средние или медианные значения для данной категории. Использование методов машинного обучения: Некоторые алгоритмы могут автоматически выявлять и обрабатывать аномалии, оставляя только значимые данные для анализа. Корректировка значений на основе правил бизнеса: Например, если известно, что максимальный стаж в отрасли не превышает 40 лет, все значения, выходящие за этот предел, можно заменить на 40. Как это делают в реальной жизни? На практике часто используют комбинированные методы. Сначала проводится детальный анализ аномальных данных: изучаются возможные причины их возникновения и степень влияния на итоговый результат. В зависимости от контекста, принимается решение о том, стоит ли удалять, корректировать или сохранять такие данные. В случаях, когда аномалия связана с реальной, но редкой ситуацией, ее могут оставить в данных, но при этом отметить, что это исключение. Если же аномалия связана с ошибкой ввода или системным сбоем, данные корректируются или удаляются. Давайте теперь перейдем к практике. Выявим аномальные значения в столбце продолжительность кредита. А затем обработаем аномалии, используя один из методов, предложенных ранее. Аномальные значения можно выявить на основе описательной статистики. Например, значения, которые значительно превышают 3 стандартных отклонения от среднего, можно считать аномальными. import numpy as np # Вычисление среднего и стандартного отклонения mean_duration = data['Duration'].mean() std_duration = data['Duration'].std() # Определение границ для аномальных значений upper_bound = mean_duration + 3 * std_duration lower_bound = mean_duration - 3 * std_duration # Фильтрация аномальных значений anomalies = data[(data['Duration'] > upper_bound) | (data['Duration'] < lower_bound)] После выявления аномалий можно их обработать разными способами, например, заменить на медианное значение. # Замена аномальных значений на медианное значение median_duration = data['Duration'].median() data['Duration'] = np.where((data['Duration'] > upper_bound) | (data['Duration'] < lower_bound), median_duration, data['Duration']) Работа с пропусками в данных Пропуски в данных могут возникать по разным причинам: ошибки при сборе данных, отсутствие информации или технические сбои. Важно учитывать, что пропуски могут существенно повлиять на результаты анализа, поэтому их необходимо корректно обрабатывать. Пропуски нужно заменять, если: Пропуски значительны по количеству: Если количество пропусков в столбце велико, анализ без их учета может быть искажен. Пропуски находятся в ключевых переменных: Если пропуски находятся в переменных, которые критически важны для анализа, их необходимо заменить, чтобы сохранить целостность данных. Данные необходимы для дальнейшего моделирования: В машинном обучении часто необходимо, чтобы данные были полными, поэтому пропуски нужно заполнять. Методы замены пропусков зависят от типа данных и контекста: Замена средним или медианным значением: Используется для числовых данных, если распределение данных симметрично или имеет выбросы. Замена модой (наиболее частым значением): Подходит для категориальных данных. Замена значением на основе данных из других колонок: Например, если пропущены значения в колонке зарплаты, их можно заполнить на основе должности, которая указана в другой колонке. Использование моделей для предсказания пропусков: Более сложный метод, где пропуски заполняются с помощью предсказательных моделей. Команды для замены пропусков в Pandas: data.fillna(value) – Замена всех пропусков в датафрейме на указанное значение. data['column'].fillna(data['column'].mean(), inplace=True) – Замена пропусков в конкретной колонке на среднее значение. data['column'].fillna(data['column'].median(), inplace=True) – Замена пропусков на медианное значение. data.fillna(method='ffill') – Заполнение пропусков предыдущим значением. data.fillna(method='bfill') – Заполнение пропусков следующим значением. # Проверка наличия пропусков missing_values = data.isnull().sum() print(missing_values) После выполнения кода мы увидим, что пропуски есть в колонках Saving accounts и Checking account. Давайте рассмотрим, как можно обработать пропуски в столбце "Checking account" с использованием различных подходов. Замена на наиболее частое значение (моду): Если категория встречается чаще других, пропуски можно заменить на нее. # Замена пропусков на наиболее частое значение most_frequent = data['Checking account'].mode()[0] data['Checking account'].fillna(most_frequent, inplace=True) Замена на специальное значение: Пропуски можно заменить на специальное значение, например, "Unknown" или "No account", если это имеет смысл в контексте данных. # Замена пропусков на 'Unknown' data['Checking account'].fillna('Unknown', inplace=True) Замена на основе данных из других колонок: Если в датасете есть другие столбцы, которые могут коррелировать с наличием или типом счета, можно использовать эти данные для заполнения пропусков. data['Checking account'] = data.groupby('Job')['Checking account'].transform(lambda x: x.fillna(x.mode()[0] if not x.mode().empty else 'Unknown')) Работа с дубликатами в данных Дубликаты в данных — это записи, которые полностью или частично повторяются. Наличие дубликатов может искажать результаты анализа, поэтому важно своевременно их обнаруживать и устранять. В Pandas для поиска дубликатов используется метод duplicated(), который возвращает логический массив (True или False) для каждой строки, указывая, является ли данная строка дубликатом. data.duplicated() — возвращает True для всех строк, которые являются дубликатами (включая первую встреченную запись). data.duplicated(keep='first') — помечает как дубликаты все строки, кроме первой встретившейся копии. data.duplicated(keep='last') — помечает как дубликаты все строки, кроме последней встретившейся копии. data.duplicated(keep=False) — помечает как дубликаты все строки, включая первую и последнюю встреченные копии. duplicates = data[data.duplicated()] print(f'Количество дубликатов: {duplicates.shape[0]}') # Просмотр дубликатов print(duplicates) После обнаружения дубликатов можно выбрать один из нескольких методов их обработки: Удаление дубликатов: Если дубликаты не содержат уникальной информации, их можно удалить. # Удаление всех дубликатов, оставляя первую встреченную запись data= data.drop_duplicates(keep='first') # Проверка количества строк после удаления дубликатов print(f'Количество строк после удаления дубликатов: {data.shape[0]}') Агрегация данных: Если дубликаты имеют различающиеся значения в некоторых полях, их можно объединить, например, с помощью среднего или суммы. # Пример агрегации (взятие среднего значения для числовых столбцов) df_aggregated = data.groupby(data.columns.tolist(), as_index=False).mean() Маркировка и дальнейший анализ: В некоторых случаях дубликаты можно оставить, но добавить метку или флаг, чтобы учесть их в дальнейшем анализе. # Добавление флага для дубликатов data['is_duplicate'] = data.duplicated(keep=False) Дубликаты могут возникать по ряду причин: Ошибки при сборе данных: Например, если один и тот же клиент был внесен в систему дважды по ошибке. Слияние нескольких источников данных: При объединении данных из разных источников одни и те же записи могут появиться несколько раз. Повторная загрузка данных: Иногда данные могут быть загружены повторно, что приводит к появлению дубликатов. Отсутствие уникальных идентификаторов: Если в данных нет уникальных идентификаторов (например, ID клиентов), система может не различать записи как уникальные, даже если они представляют разных людей или события. Вывод В этой заметке я постарался раскрыть все возможные кейсы применения Pandas в Data Sciencе проектах. Описал практические приемы. Все это пригодится вам в следующих статьях из цикла статей для начинающих вкатываться в Data Sciеnce и Machine Learning. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Поиск удаленной работы в 2024 году Решил я написать пост о том как я искал в этом году удаленную работу в сфере DS/ML/DA/CV/NLP.Я не могу сказать, что искал работу сильно активно, но если видел интересные проекты и позиции, то откликался.В этом посте я хочу поделиться своими наблюдениями и рейтингом ресурсов по поиску работы:6. @g_jobbot getmatch - телеграм бот с вакансиями. Из плюсов можно подписать на определённый тип вакансии и условия работы (зарплата, удаленка и т.д.) Мне бот не понравился, ответов в случае отклика практически нет и они в основном по вакансиям Яндекса.5. Различные job boards. Ссылка на список. Еще больше во вложенном файле. Тут у меня за всё время был один ответ с https://wellfound.com/ (бывший angellist jobs) с тестовым заданием.4. linkedin - много крутых вакансий, много удаленки. Практически 0 ответов если откликаешься сам. Но достаточно часто рекрутеры пишут в личку. Еще из рабочих вариантов самому писать рекрутерам из понравившихся вакансий. Во всяком случае это даёт хоть какие-то интервью.3. hh.kz - так как я из Казахстана, то в основном хороший ресурс для поиска локальной работы. Удаленки почти нет.2. singularis slack - один из лучших вариантов для поиска удаленной работы. Из плюсов в канале jobs публикуют вакансии с вилками и контактами HR или нанимающего менеджера. Большинство отвечают быстро, много удаленки, часто хорошие зарплаты. Рекомендую.1. Телеграм каналы с вакансиями. Это лучший источник вакансий и коммуникаций. Сам я нашел текущую работу именно там. Чаще всего вакансии публикуются с вилками и контактами HR или нанимающего менеджера.Вложенный файл с job boards и ссылку на мою папку каналов с вакансиями вы найдете у меня в телеграм канале Подписывайтесь =) Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Deep dive into LLM Part Two In the first part we discussed the practical part of deep dive into LLM.In this part we will talk about key papers that will help in understanding LLM and passing interviews =) But more on that later.It all starts with the first GPTThen I recommend reading the paper about InstructGPT. The topic of training with feedback from a person is discussed there.Then there are a couple of interesting papers:- SELF-INSTRUCT- Information Retrieval with Contrastive LearningThen I recommend that you familiarize yourself with two truly iconic papers: LORA and QLORA, which solve the following problems:- learning speed- computing resources- memory efficiencyTwo more equally important paperpers are PPO and DPO. Understanding these works will help in reward modeling.And finally:- Switch Transformers  - as a base Mixtures of experts- Mixtral of Experts  - as Open Source SOTA- Llama 2Happy reading everyone ### Погружение в LLM часть вторая В первой части мы разобрали практическую часть погружения в LLM. В этой части мы поговорим про ключевые пейперы, которые помогут в понимании LLM и прохождение собеседований =) Но об этом позже. Все начинается с первой гпт Затем рекомендую прочитать работу про InstructGPT. Там раскрыта тема обучения с фидбеком от человека. Дальше есть пара интересных пейперов: SELF-INSTRUCT Information Retrieval with Contrastive Learning Затем рекомендую ознакомиться с двумя воистину знаковых пейпера: LORA и QLORA, которые решают следующие проблемы: скорость обучения вычислительные ресурсы эффективность памяти Еще два не менее важных пейпера PPO и DPO. Понимание этих работ поможет в ревард моделинге. Ну и на последок: Switch Transformers - как база Mixtures of experts Mixtral of Experts - как Open Source SOTA Llama 2 Всем приятного чтения Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Deep dive into LLM Part One I've started delving deeper into LLM, and personally, I find it much easier to dive myself through practice.This way, one can grasp all the key concepts and outline a list of papers for further exploration.I began with the StackLLaMA note: A hands-on guide to train LLaMA with RLHF Here, you can immediately familiarize yourself with the concepts of Reinforcement Learning from Human Feedback, effective training with LoRA, PPO.You'll also get acquainted with the Hugging Face library zoo: accelerate, bitsandbytes, peft, and trl.The note uses the StackExchange dataset, but for variety, I can recommend using the Anthropic/hh-rlhf datasetIn the second part, we'll go through key papers. ### Погружение в LLM часть первая Я тут начал погружаться в LLM чуть глубже и лично для меня гораздо проще начинать погружение через практику. Таким образом можно понять все ключевые концепции и наметить себе список пейперов для дальнейшего ознакомления. Начал я с заметки StackLLaMA: A hands-on guide to train LLaMA with RLHF Тут вы сразу сможете ознакомиться с концепциями Reinforcement Learning from Human Feedback, эффективной тренировкой с помощью LoRA, PPO. Так же вы познакомитесь с зоопарком библиотек huggingface: accelerate, bitsandbytes, peft и trl. В заметке используется StackExchange датасет, но для разнообразия могу посоветовать вам использовать датасет Anthropic/hh-rlhf Во второй части пройдемся по ключевым пейперам Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Какие фреймворки должен знать продакт-менеджер Product Management требует глубокого понимания рынка, конкуренции, болевых точек и потребностей клиентов. Задачи, которые решает продакт менеджер очень разнообразны — от принятия важных решений по продукту до сотрудничества с маркетологами, приходится часто переключаться на контекст и посещать множество встреч. Вот почему продакт менеджеры обычно полагаются на разные фреймворки для оптимизации рабочих процессов, создания повторяемых процессов и поддержки устойчивого развития продукта. В этой заметке я постараюсь описать лучшие фреймворки и объясню, как получить максимальную отдачу от каждого из них. Гибкие методологии и фреймворки Вот несколько Agile- структур и подходов, которые можно использовать в циклах разработки продуктов. Lean Canvas Lean Canvas был разработан, чтобы помочь стартапам проанализировать сильные и слабые стороны их бизнес-модели. Он был разработан Эшем Маурья как вариант бизнес -модели Canvas (первоначально созданной Александром Остервальдером). Технически говоря, Lean Canvas — это одностраничный документ, разделенный на девять блоков. Каждый сегмент ставит перед вами задачу определить области риска и возможностей, устранить болевые точки клиентов и создать действенный план для запуска и развития бизнеса. Они имеют следующие заголовки и описания: Сегменты клиентов – перечислите своих целевых клиентов и пользователей. Ранние последователи – перечислите характеристики ваших идеальных клиентов. Проблема – перечислите 3 основные проблемы вашего клиента. Существующие альтернативы – перечислите, как эти проблемы решаются сегодня. Потоки доходов – перечислите источники доходов. Решение – обрисуйте возможное решение для каждой проблемы. Уникальное ценностное предложение – единое, ясное и убедительное сообщение, которое превращает ничего не подозревающего посетителя в заинтересованного потенциального клиента. Концепция высокого уровня – опишите свою идею простыми словами. Вы даже можете привести аналогию X вместо Y (например, YouTube = Flickr для видео). Каналы – укажите свой путь к клиентам. Ключевые показатели – перечислите ключевые цифры, которые говорят вам, как идет ваш бизнес. Структура затрат – перечислите свои постоянные и переменные затраты. Несправедливое преимущество – то, что невозможно легко скопировать или купить. Lean Canvas — это не просто статический лист со всей информацией о вашей бизнес-модели. Это живой документ, который регулярно обновляется заинтересованными сторонами согласно отзывам клиентов. Рекомендую заполнять эти поля в том порядке, в котором они указаны выше: это проще и, по опыту, требует меньше времени. Lean Canvas помогает визуализировать предлагаемую бизнес-модель и подумать о том, как мы можем решить реальную проблему, а не просто создавать функции ради функций. Разработка, основанная на функциях Разработка на основе функций (FDD) — это ключевая концепция Agile, которую необходимо знать менеджерам по продуктам, уже использующим другие гибкие методы. В последнее время этот подход стал более распространенным. Разработка на основе функций состоит из пяти основных процессов, а именно: Разработайте общую модель. Рассмотрите все требования проекта и посмотрите на картину в целом: что должен делать ваш новый продукт? Как будет работать система и как будут связаны разные ее части? Эта архитектура послужит основой для последующих шагов процесса разработки. Создайте список функций. Определите и расставьте приоритеты в списке функций, которые необходимо разработать с участием заинтересованных сторон (например, маркетологов, дизайнеров, руководителей высшего звена и даже клиентов). Планируйте по функциям. Допустим, вы создаете систему здравоохранения, и одна из функций в вашем списке — «назначение встреч». Чтобы повысить эффективность, эту эпопею следует разбить на ряд более мелких задач, например, изменение встречи, настройка уведомлений и т. д. Дизайн по характеристикам. Здесь команда разработчиков создаст подробный пользовательский интерфейс и UX для каждой функции, возможно, даже прототип. Создавайте по функциям. Как только этот дизайн будет одобрен командой продукта/заинтересованными сторонами, эта функция будет создана и реализована вместе с другими в рамках спринта. И цикл повторяется. FDD хорош, потому что он поддерживает быстрое развитие (что является обязательным условием в этой конкурентной среде) и позволяет команде разработчиков сосредоточиться на ценности, которую они могут принести клиентам. Функции должным образом планируются, разрабатываются, тестируются и проверяются, что гарантирует, что ресурсы разработки не будут потрачены зря. Записаться на курс Управление AI и ML продуктами. Курс позволит вам получить обширные навыки для работы над практически любым ML-проектом. Минимально жизнеспособный продукт (MVP) Многие стартапы терпят неудачу, потому что тратят месяцы – даже годы – пытаясь создать «идеальный» продукт, вместо того, чтобы прислушиваться к мнению своих клиентов. Но при разработке новых продуктов победа не может быть достигнута медленными и постоянными усилиями, а адаптируемыми, быстро обучающимися командами. И вот здесь на помощь приходит MVP. Минимально жизнеспособный продукт , или MVP, — это создание базовой версии идеи вашего продукта, обмен ею с целевой аудиторией, сбор отзывов клиентов и повторение вашей идеи. Эта концепция, впервые предложенная Эриком Райсом, является фундаментальной концепцией его методологии бережливого стартапа. MVP включает в себя только основные функции и возможности, необходимые для решения проблемы клиента или предоставления пользы пользователю . Вместо того, чтобы гоняться за совершенством, команды работают над достижением соответствия продукта рынку быстрее, чем конкуренты, и улучшением пользовательского опыта на каждом этапе. CustDev Как и MVP, CustDev — это скорее стратегический подход, чем структура, но это все же концепция, с которой должен ознакомиться каждый менеджер по продукту. CustDev предполагает раннее и частое взаимодействие с клиентами, чтобы получить представление об их болевых точках, потребностях, предпочтениях и поведении. Этот процесс состоит из четырех ключевых этапов: обнаружение клиентов, проверка клиентов, создание клиентов и построение компании. Вот некоторые из наших главных советов для проведения CustDev: Подготовка имеет решающее значение. Заранее проведите большое исследование. Выстраивайте гипотезы для проверки ваших предположений о вашем новом продукте, целевой аудитории, компании и т. д. И тщательно выбирайте участников – выбирайте потенциальных платящих пользователей, а не просто любопытных людей. Задавайте открытые вопросы. Не просите собеседника сказать вам, является ли подход X хорошей идеей, будет ли он использовать функцию X и так далее. Вместо этого спросите, как они относятся к X или когда они в последний раз его использовали. Пусть ваши клиенты скажут вам, что они на самом деле думают. Практикуйте эмпатию. Постарайтесь сразу же успокоить собеседника – объясните цель звонка и как отвечать на вопросы. Сохраняйте легкую атмосферу и плавный ход разговора, но слушайте больше, чем говорите. Запишите интервью. Скорее всего, ваше собеседование пройдет онлайн. Рекомендуем записать его, чтобы не перефразировать ответы клиентов. Их точная формулировка может дать подсказку о том, что следует улучшить. Механизмы расстановки приоритетов Вот две наиболее эффективные структуры для планирования продукта, управления рабочей нагрузкой и организации приоритетов проекта. MoSCoW MoSCoW — одна из самых популярных систем расстановки приоритетов, и это правильно. Это просто, практично, легко запоминается и может использоваться в самых разных контекстах. MoSCoW был разработан в 90-х годах Даем Клеггом, который в то время работал в Oracle. Каждая заглавная буква в MoSCoW обозначает уровень приоритета, от высокого к низкому. Буквы означают « должен иметь», «должен иметь», « мог бы иметь» и «не иметь». Чтобы продемонстрировать, как можно применять каждый из них, предположим, что вы разрабатываете MVP для электронной коммерции и вам необходимо расставить приоритеты в требованиях к продукту. У вас есть список функций и возможностей (например, «создать учетную запись», «обзоры продуктов», «система обработки платежей»), но вам нужно решить, какие из них реализовать в первую очередь. Must-have— это требования высшего приоритета. Приложение позволять клиентам просматривать каталог товаров и совершать покупки онлайн. Should-haves — это требования второстепенного приоритета. Приложение позволять клиентам создавать учетную запись и сохранять информацию о доставке и оплате. Could-haves — желательные дополнения. Было бы здорово, если бы в приложении оставлять отзывы о товарах. Won’t-haves — это второстепенные функции, которые не обязательно включать в первоначальный выпуск. На данный момент приложение рекомендовать клиентам новые продукты на основе их прошлых покупок. Не попадайтесь в ловушку, отмечая каждую функцию или задачу как обязательную. MoSCoW работает только тогда, когда команда честно и реалистично оценивает важность требований к продукту. Записаться на курс Управление AI и ML продуктами. Курс позволит вам получить обширные навыки для работы над практически любым ML-проектом. Модель оценки RICE RICE — еще одна надежная система определения приоритетов, которую всегда можно иметь под рукой. Это изобретение Шона Макбрайда, бывшего менеджера по продукту компании Intercom, который хотел облегчить задачу определения приоритетов в дорожной карте продукта. RICE — это аббревиатура от Reach, Impact, Confidence и Effort — четырех ключевых факторов, с помощью которых можно измерить каждую функцию, гипотезу или пользовательскую историю. Чтобы продемонстрировать, как RICE работает на практике, предположим, что вы разработали приложение для социальных сетей и решаете, какие улучшения продукта реализовать в первую очередь. Одним из вариантов является инструмент перевода, который автоматически переводит сообщения и комментарии на разные языки, делая платформу более доступной для пользователей, не говорящих по-английски. Мы можем оценить уровень приоритета функции по следующим факторам: Reach — это количество людей, которые будут использовать эту функцию в течение определенного периода времени. Вы можете подсчитать, что половина вашей текущей ежемесячной базы активных пользователей будет использовать функцию перевода каждый квартал. Таким образом, охват составляет 10 тысяч клиентов в квартал. Impact количественно определяет ценность, которую новая функция добавит вашему продукту. Чтобы помочь в этом, Intercom разработала « шкалу с множественным выбором : 3 для «массивного воздействия», 2 для «высокого», 1 для «среднего», 0,5 для «низкого» и 0,25 для «минимального». Допустим, вы решаете. что функция перевода имеет оценку влияния 1 на основе результатов ваших недавних проверок гипотез. Confidence. Если у вас нет всех данных, подтверждающих ваш энтузиазм по поводу какой-либо функции, вы можете дать ей оценку уверенности. Измерьте это в процентах: 20% — это «высокая уверенность», 50% — «низкая уверенность», 80% — «средняя уверенность», а 100% — «высокая уверенность». Effort . Это оценка количества времени и ресурсов, которые потребуются для реализации новой функции. Intercom рекомендует делать это, рассчитывая «человеко-месяцы» — сколько членов команды будут заниматься этой функцией каждый месяц до завершения. Итак, формула определения приоритета: (Reach х Impact х Confidence) / Усилия = Оценка RICE. Системы показателей продукта Две надежные системы для точного измерения производительности продукта. AARRR Система показателей AARRR построена по образцу конверсионной или маркетинговой воронки . Впервые его разработал Дэйв МакКлюр, венчурный капиталист и основатель 500 Startups. Для облегчения произношения он назвал эту структуру «Пиратскими метриками». Аббревиатура расшифровывается как «Привлечение», «Активация», «Удержание», «Доход» и «Реферал». Каждая метрика соответствует этапу пути клиента. Изучая изменения (или их отсутствие) в поведении пользователей на каждом этапе, PDM могут выявить области спада и измерить вовлеченность или неудовлетворенность пользователей. Вооружившись этими данными, они будут лучше подготовлены к целевому улучшению продукта. AARRR: Привлечение означает, сколько людей мы привлекли на платформу через такие каналы, как социальные сети, SEO или оплата за клик (PPC). Его можно измерить по рейтингу кликов, запросам на обслуживание и активности сайта. Активация— это количество людей, которые создали учетную запись и начали использовать функции продукта. Удержание — это количество пользователей, которые остались после регистрации. Выручка - определяется ежемесячным регулярным доходом (MRR) или годовым регулярным доходом (ARR). Рефералы — это количество пользователей, рекомендующих продукт другим. OKR OKR не сразу стал популярным, когда его впервые представил Эндрю Гроув из Intel в 1970-х годах. Фактически, он получил широкое распространение только тогда, когда Джон Дорр представил его Google в конце 90-х. Но с тех пор бесчисленное количество организаций выбирают эту систему постановки целей и показателей. Цели и ключевые результаты, или OKR, помогают менеджерам по продукту устанавливать цели, соответствующие видению компании и стратегии продукта . В основном это позволяет командам сосредоточиться на результате, а не на задачах, необходимых для достижения цели. OKR обычно внедряется ежеквартально (проверки каждые 3 месяца). Чтобы эффективно использовать эту структуру, начните с выбора амбициозной и измеримой цели продукта. Затем установите 3–5 ключевых результатов , которые помогут вам отслеживать прогресс в достижении этой цели. Вот пример. Цель: мы хотим увеличить вовлеченность пользователей вдвое в течение следующего квартала. Ключевые результаты: Увеличение ежемесячных активных пользователей на 20 % Увеличьте количество функций, используемых каждым пользователем, на 10 %. Увеличьте среднюю продолжительность сеанса на 15 %. Ключевые результаты должны быть конкретными, привязанными ко времени (крайний срок – конец квартала) и подкреплены планом действий. Например, чтобы увеличить количество активных пользователей в месяц, ваша команда разработчиков может улучшить процесс адаптации и/или поэкспериментировать с новым текстом UX. Чтобы не сбиться с пути, вы можете организовать эти задачи в дорожной карте продукта. Избегайте постановки слишком простых целей, таких как «Увеличение продаж». Будьте как можно более конкретны, потому что если вы достигнете своей цели слишком быстро, это признак того, что она недостаточно амбициозна. Выводы Управление продуктом многогранно. Не существует универсального подхода, и каждая организация имеет свои собственные процессы и предпочтительные способы решения проблем, принятия решений, определения приоритетов рабочих нагрузок и отслеживания успеха продукта. Тем не менее, я считаю, что вышеуказанные структуры и методологии по управлению продуктов являются одними из наиболее полезных в отрасли. Они динамичны, практичны и просты в применении. Записаться на курс Управление AI и ML продуктами. Курс позволит вам получить обширные навыки для работы над практически любым ML-проектом. ### Machine learning pipeline-basics. Cookiecutter and Hydra In Data Science courses, homework and projects are done in Jupyter Notebooks and students are not taught to write pipelines. The fact is that working in Jupyter Notebooks, despite its convenience, also has disadvantages. For example, you build several types of models with multiple options for filling in gaps (mean, median), generate a feature engineering set, and apply different options for splitting the sample. You can put all this code in one Jupyter Notebooks and log metrics and configs. The code will turn out to be cumbersome and slow. To run experiments, you will need to either jump over or comment on cells that don't need to be run. To solve these problems, I recommend using pipeline to automate machine learning workflows. The main purpose of creating a pipeline is control. A well-organized pipeline makes implementation more flexible. Follow the link to view the sample code for the pipeline. The structure is as follows: config-folder with configuration files in yaml format data-folder with data files external — data from external sources interim-data separation raw — raw data processed — data after processing experiments-configs, logs of model results models-folder for storing models src-source code. Contains code for working with data, evaluating models, supporting functions, training models, and working with attributes Working with the pipeline consists of the following steps: Creating configs Preparing attributes Splitting into samples Model Training Measuring model quality Cookiecutter Data Science Let's now try to look at different pipeline development practices. The first thing I would recommend is to try the project structure: cookiecutter This structure is quite logical, standardized, and flexible. All you need is to install it and start the project: pip install cookiecutter cookiecutter -c v1 https://github.com/drivendata/cookiecutter-data-science The directory structure of your new project looks like this: ├── LICENSE ├── Makefile <- Makefile with commands like `make data` or `make train` ├── README.md <- The top-level README for developers using this project. ├── data │ ├── external <- Data from third party sources. │ ├── interim <- Intermediate data that has been transformed. │ ├── processed <- The final, canonical data sets for modeling. │ └── raw <- The original, immutable data dump. │ ├── docs <- A default Sphinx project; see sphinx-doc.org for details │ ├── models <- Trained and serialized models, model predictions, or model summaries │ ├── notebooks <- Jupyter notebooks. Naming convention is a number (for ordering), │ the creator's initials, and a short `-` delimited description, e.g. │ `1.0-jqp-initial-data-exploration`. │ ├── references <- Data dictionaries, manuals, and all other explanatory materials. │ ├── reports <- Generated analysis as HTML, PDF, LaTeX, etc. │ └── figures <- Generated graphics and figures to be used in reporting │ ├── requirements.txt <- The requirements file for reproducing the analysis environment, e.g. │ generated with `pip freeze > requirements.txt` │ ├── setup.py <- makes project pip installable (pip install -e .) so src can be imported ├── src <- Source code for use in this project. │ ├── __init__.py <- Makes src a Python module │ │ │ ├── data <- Scripts to download or generate data │ │ └── make_dataset.py │ │ │ ├── features <- Scripts to turn raw data into features for modeling │ │ └── build_features.py │ │ │ ├── models <- Scripts to train models and then use trained models to make │ │ │ predictions │ │ ├── predict_model.py │ │ └── train_model.py │ │ │ └── visualization <- Scripts to create exploratory and results oriented visualizations │ └── visualize.py │ └── tox.ini <- tox file with settings for running tox; see tox.readthedocs.io For your projects, you can slightly redesign the structure, for example: I don't need the src/features, reports, and references folders in my Computer Vision projects. More details can be found here: Git repository Cookiecutter Data Science Adding Hydra In this part of the article, we will talk about libraries for working with configurations for machine learning projects — Hydra. What exactly is the problem and why did I start using Hydra? When running Python scripts, many arguments are added, although sometimes they can be grouped. Here is an example of such a script: parser.add_argument('data', metavar='DIR', help='path to dataset') parser.add_argument('-a', '--arch', metavar='ARCH', default='resnet18', choices=model_names, help='model architecture: ' + ' | '.join(model_names) + ' (default: resnet18)') parser.add_argument('-j', '--workers', default=4, type=int, metavar='N', help='number of data loading workers (default: 4)') parser.add_argument('--epochs', default=90, type=int, metavar='N', help='number of total epochs to run') parser.add_argument('--start-epoch', default=0, type=int, metavar='N', help='manual epoch number (useful on restarts)') parser.add_argument('-b', '--batch-size', default=256, type=int, metavar='N', help='mini-batch size (default: 256), this is the total ' 'batch size of all GPUs on the current node when ' 'using Data Parallel or Distributed Data Parallel') parser.add_argument('--lr', '--learning-rate', default=0.1, type=float, metavar='LR', help='initial learning rate', dest='lr') parser.add_argument('--momentum', default=0.9, type=float, metavar='M', help='momentum') parser.add_argument('--wd', '--weight-decay', default=1e-4, type=float, metavar='W', help='weight decay (default: 1e-4)', .... Switching to configuration files is a common solution to control the growing complexity. Configuration files can be hierarchical and can help reduce the complexity of the code that defines command-line arguments. But they also have their drawbacks. For example: While experimenting, you may need to run the application with different configuration options. At first, you can simply change the configuration file before each run, but you will soon find that it is difficult to track changes associated with each run. Configuration files become monolithic. But if, for example, you want your code to use different configuration parameters, say, one for the ImageNet dataset and one for the CIFAR-10 dataset, you have two options: maintain two configuration files, or put both parameters in a single configuration file and somehow use only what you want. you need it at runtime. Well, the solution to all the above inconveniences is Hydra. Hydra-allows you to create a composition of configurations. The composition can work both with the configuration file and on the command line. At the same time, everything in the compiled configuration can also be overridden via the command line. Usage example: Conf/config.yaml file defaults: - dataset: cifar10 conf/dataset/imagenet.yaml file dataset: name: imagenet path: /datasets/imagenet File app.py import hydra from omegaconf import DictConfig @hydra.main(config_path="conf/config.yaml") def my_app(cfg: DictConfig) -> None: ... if __name__ == "__main__": my_app() The default dataset parameter will be used at startup. But you can also pass the parameter to the console as well: python app.py dataset.path = /datasets/cifar10 Another cool feature: multirun is Hydra's ability to run your function multiple times, creating a new configuration object each time. This is very convenient for checking parameters without writing additional functions. For example, we can view all 4 combinations (2 datasets X 2 optimizers): python app.py —multirun dataset= imagenet, cifar10 optimizer=adam, nesterov And this is how it looks in my project To learn more about Hydra, I suggest reading and watching: Hydra Website Hydra — A fresh look at configuration for machine learning projects Conclusion In this mini-note, I tried to describe the approach to pipeline development, problems with configs that you encounter when writing pipelines, and some of the features that Hydra offers. ### Machine learning pipeline - основы. Cookiecutter и Hydra В курсах по Data Science домашние работы и проекты делаются в Jupyter Notebooks и студентов не учат писать пайплайны. Дело в том, что работа в Jupyter Notebooks не смотря на удобство несет в себе в том числе и недостатки. Например, вы строите несколько типов моделей с несколькими вариантами заполнения пропусков (среднее, медиана), генерируете набор feature engineering и применяете разные варианты разбиения выборки. Можно разместить весь этот код в один Jupyter Notebooks и логгировать метрики и конфиги. Код получится громоздкий и не поворотливый. Для запуска экспериментов надо будет или перескакивать или комментировать ячейки, которые не нужно запускать. Для решения этих проблем рекомендую использовать pipeline для автоматизации рабочих процессов машинного обучения. Основная цель создания пайплайна - это контроль. Хорошо организованный пайплайн делает реализацию более гибкой. По ссылке можно ознакомиться с примером кода для пайплайна. Структура следующая: config - папка с файлами конфигурации в формате yaml data - папка с файлами данных external - данные из внешних источников interim - разделение данных raw - необработанные данные processed - данные после обработки experiments - конфиги, логи результатов модели models - папка для хранения моделей src - исходный код. Содержит код для работы с данными, оценки моделей, вспомогательные функции, обучения моделей, работы с признаками Работа с пайплайном состоит из следующих этапов Создание конфигов Подготовка признаков Разбиение на выборки Обучение модели Измерение качества модели Cookiecutter Data Science Давайте теперь попробуем посмотреть на разные практики разработки пайплайнов. Первое, что я бы советовал это попробовать структуру проекта: cookiecutter Эта структура достаточно логичная, стандартизированная и гибкая. Всё что вам нужно, установить его и стартануть проект: pip install cookiecutter cookiecutter -c v1 https://github.com/drivendata/cookiecutter-data-science Структура каталогов вашего нового проекта выглядит следующим образом: ├── LICENSE ├── Makefile <- Makefile with commands like `make data` or `make train` ├── README.md <- The top-level README for developers using this project. ├── data │ ├── external <- Data from third party sources. │ ├── interim <- Intermediate data that has been transformed. │ ├── processed <- The final, canonical data sets for modeling. │ └── raw <- The original, immutable data dump. │ ├── docs <- A default Sphinx project; see sphinx-doc.org for details │ ├── models <- Trained and serialized models, model predictions, or model summaries │ ├── notebooks <- Jupyter notebooks. Naming convention is a number (for ordering), │ the creator's initials, and a short `-` delimited description, e.g. │ `1.0-jqp-initial-data-exploration`. │ ├── references <- Data dictionaries, manuals, and all other explanatory materials. │ ├── reports <- Generated analysis as HTML, PDF, LaTeX, etc. │ └── figures <- Generated graphics and figures to be used in reporting │ ├── requirements.txt <- The requirements file for reproducing the analysis environment, e.g. │ generated with `pip freeze > requirements.txt` │ ├── setup.py <- makes project pip installable (pip install -e .) so src can be imported ├── src <- Source code for use in this project. │ ├── __init__.py <- Makes src a Python module │ │ │ ├── data <- Scripts to download or generate data │ │ └── make_dataset.py │ │ │ ├── features <- Scripts to turn raw data into features for modeling │ │ └── build_features.py │ │ │ ├── models <- Scripts to train models and then use trained models to make │ │ │ predictions │ │ ├── predict_model.py │ │ └── train_model.py │ │ │ └── visualization <- Scripts to create exploratory and results oriented visualizations │ └── visualize.py │ └── tox.ini <- tox file with settings for running tox; see tox.readthedocs.io Для своих проектов вы можете немного переделал структуру, например: мне в проектах Computer Vision не нужна папки src/features, reports и references. Более подробно можно почитать тут: Git репозиторий Cookiecutter Data Science Добавляем Hydra В этой части заметки мы поговорим библиотеки для работы конфигурациями для проектов машинного обучения - Hydra. В чем собственно проблема и почему я стал использовать Hydra? При запуске Python скриптов добавляют много аргументов, хотя иногда их можно и сгруппировать. Вот пример такого скрипта: parser.add_argument('data', metavar='DIR', help='path to dataset') parser.add_argument('-a', '--arch', metavar='ARCH', default='resnet18', choices=model_names, help='model architecture: ' + ' | '.join(model_names) + ' (default: resnet18)') parser.add_argument('-j', '--workers', default=4, type=int, metavar='N', help='number of data loading workers (default: 4)') parser.add_argument('--epochs', default=90, type=int, metavar='N', help='number of total epochs to run') parser.add_argument('--start-epoch', default=0, type=int, metavar='N', help='manual epoch number (useful on restarts)') parser.add_argument('-b', '--batch-size', default=256, type=int, metavar='N', help='mini-batch size (default: 256), this is the total ' 'batch size of all GPUs on the current node when ' 'using Data Parallel or Distributed Data Parallel') parser.add_argument('--lr', '--learning-rate', default=0.1, type=float, metavar='LR', help='initial learning rate', dest='lr') parser.add_argument('--momentum', default=0.9, type=float, metavar='M', help='momentum') parser.add_argument('--wd', '--weight-decay', default=1e-4, type=float, metavar='W', help='weight decay (default: 1e-4)', .... Распространенным решением, позволяющим контролировать растущую сложность, является переход на файлы конфигураций. Файлы конфигурации могут быть иерархическими и могут помочь уменьшить сложность кода, определяющего аргументы командной строки. Но и у них есть свои недостатки. Например: Во время экспериментов вам может понадобиться запустить приложение с различными параметрами конфигурации. Сначала вы можете просто изменять файл конфигурации перед каждым запуском, но вскоре вы поймете, что трудно отслеживать изменения, связанные с каждым запуском. Файлы конфигурации становятся монолитными. Но если вы, например, хотите, чтобы ваш код использовал разные параметры конфигурации, скажем, один для набора данных ImageNet и один для набора данных CIFAR-10, у вас есть два варианта: поддерживать два файла конфигурации или поместить оба параметра в один файл конфигурации и каким-то образом используйте только то, что вам нужно во время выполнения. Ну, а решение всех вышеперечисленных неудобств - Hydra. Hydra — позволяет создавать композицию конфигураций. Композиция может работает как с файлом конфигурации, так и в командной строке. При этом всё в составленной конфигурации также может быть переопределено через командную строку. Пример использования: Файл conf/config.yaml defaults: - dataset: cifar10 Файл conf/dataset/imagenet.yaml dataset: name: imagenet path: /datasets/imagenet Файл app.py import hydra from omegaconf import DictConfig @hydra.main(config_path="conf/config.yaml") def my_app(cfg: DictConfig) -> None: ... if __name__ == "__main__": my_app() При запуске будет использоваться параметр dataset по умолчанию. Но вы так же передать параметр и консоле: python app.py dataset.path = /datasets/cifar10 Еще одна крутая фишка: multirun — это возможность Hydra запускать вашу функцию несколько раз, каждый раз создавая новый объект конфигурации. Это очень удобно для проверки параметров без написания дополнительных функций. Например, мы можем просмотреть все 4 комбинации (2 набора данных X 2 оптимизатора): python app.py —multirun dataset= imagenet, cifar10 optimizer=adam, nesterov А так это выглядит у меня в проекте Чтобы узнать больше о Hydra предлагаю почитать и посмотреть: Сайт Hydra Hydra — A fresh look at configuration for machine learning projects Как эффективно проводить эксперименты, Роман Суворов Артур Кузин: DL Pipelines tips & tricks Заключение В этой мини заметке я постарался описать подхода к разработке пайплайнов, проблемы с конфигами, с которым сталкиваешься при написании пайплайнов и часть функций, которые предлагает Hydra. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Evidently and custom metrics Evidently AI is a library that helps analyze machine learning models during testing or monitoring production. The tool generates interactive visual reports and JSON profiles from pandas DataFrame or csv files. There are currently 6 reports available: Data Drift - detects changes in feature distribution Numerical Target Drift - detects numerical target changes and feature behavior Categorical Target Drift - detects changes in categorical target and feature behavior Regression Model Performance - analyzes regression model performance and model errors Classification Model Performance - Analyzes the performance and errors of the classification model. Works for both binary and multiclass models. Probabilistic Classification Model Performance - Analyzes the performance of a probabilistic classification model, the quality of model calibration, and model errors. Works for both binary and multiclass models. Metrics A metric is a component that evaluates a specific aspect of data or model quality. Metric Preset A metrics preset is a pre-built report that aggregates metrics for a specific use case (for example, DataDriftPreset, RegressionPreset, etc.). How it works? Generate a report on reference and current datasets Reference dataset is the base dataset for comparison. This could be a training set or previous production data. Current dataset - the second dataset compared with the base one. It may contain the latest production data. Implementation of custom metrics There are times in work when you need to monitor metrics that are not available in Evidently. For example, in telecom they really like the lift metric. Business loves her and understands her very well. You can read more about lift metrics here. To add a new metric you need to do two things: Implement metric Add visualization to plotly - optional The official documentation has an example of implementing a custom metric: https://docs.evidentlyai.com/user-guide/customization/add-custom-metric-or-test But we will take a more complicated route and implement the metric directly in Evidently in order to then make a pull request Where to add: /src/evidently/calculations - add a metric depending on the task (classification, regression, etc.) /src/evidently/metrics — add code for calculating metrics depending on the task /src/evidently/renderers/html_widgets.py - visualization of metrics /src/evidently/metrics/init.py — initialize metrics /src/evidently/metric_results.py - add visualization The metric code can be viewed in the already accepted pull request Metric call #probabilistic binary classification classification_report = Report(metrics=[ ClassificationLiftCurve(), ClassificationLiftTable(), ]) classification_report.run(reference_data=bcancer_ref, current_data=bcancer_cur) classification_report ### Evidently и кастомные метрики Evidently AI это библиотека, которая помогает анализировать модели машинного обучения во время проверки или мониторинга продакшена. Evidently AI Инструмент генерирует интерактивные визуальные отчеты и профили JSON из файлов pandas DataFrame или csv. На данный момент доступно 6 отчетов: Data Drift - обнаруживает изменения в распределении фичей Numerical Target Drift - обнаруживает изменения числового таргета и поведение фичей Categorical Target Drift - обнаруживает изменения в категориального таргета и поведение фичей Regression Model Performance - анализирует производительность регрессионной модели и ошибки модели Classification Model Performance - анализирует производительность и ошибки модели классификации. Работает как для бинарных, так и для мультиклассовых моделей. Probabilistic Classification Model Performance - анализирует производительность модели вероятностной классификации, качество калибровки модели и ошибки модели. Работает как для бинарных, так и для мультиклассовых моделей. Метрики Метрика — это компонент, который оценивает определенный аспект качества данных или модели. Метрики Evidently AI Метрики Evidently AI Пресет метрик Пресет метрик — это предварительно созданный отчет, который объединяет метрики для конкретного варианта использования (например, DataDriftPreset, ReгрессияPreset и т. д.). Пресет метрик Evidently AI https://docs.evidentlyai.com/readme/core-concepts Как это работает? Создайте отчет по эталонным и текущим наборам данных Reference dataset - это базовый набор данных для сравнения. Это может быть набор данных для обучения или предыдущие данные продакшена. Current dataset - второй набор данных, сравниваемый с базовым. Он может содержать самые последние данные продакшена. Как работает Evidently AI Реализация кастомной метрики Бывают случае в работе, когда необходимо мониторить метрики, которых нет в Evidently. Например, в телекоме очень любят метрику lift. Бизнес её любит и очень хорошо понимает. Подробнее можно про lift метрику можно почитать тут. Для добавлении новой метрики необходимо сделать две вещи: Реализовать метрику Добавить визуализацию на plotly - по желанию В официальной документации есть пример реализации кастомной метрики: https://docs.evidentlyai.com/user-guide/customization/add-custom-metric-or-test Но мы пойдем более сложным путем и реализуем метрику сразу в Evidently для того, что бы потом сделать pull request Куда добавлять: /src/evidently/calculations - добавить метрику в зависимости от задачи (классификация, регрессия и т.д.) /src/evidently/metrics - добавить код расчета метрики в зависимости от задачи /src/evidently/renderers/html_widgets.py - визуализация метрик src/evidently/metrics/init.py - инициализируем метрики src/evidently/metric_results.py - добавить визуализацию Код метрики и можно посмотреть в уже принятом pull request Вызов метрики #probabilistic binary classification classification_report = Report(metrics=[ ClassificationLiftCurve(), ClassificationLiftTable(), ]) classification_report.run(reference_data=bcancer_ref, current_data=bcancer_cur) classification_report Lift metric table Evidently AI Lift metric curve Evidently AI Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Налоговый календарь для ИП в Казахстане Сделал небольшой сервис для всех индивидуальных предпринимателей в Казахстане, особенно для тех, кто находится на упрощенной системе налогообложения. Если вы когда-либо забывали о предстоящих налоговых обязательствах или тратили много времени на поиск актуальной информации о налогах, этот сервис создан специально для вас. Сервис позволяет в один клик добавить в свой календарь полную информацию о предстоящих налогах и платежах для индивидуальных предпринимателей в Казахстане находящихся на упрощенке. Налоговый календарь для ИП в Казахстане Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Стань экспертом в Machine Learning и MLOps Набор на курс пока закрыт Я с недавних пор стал партнером и преподавателем в Risoma School. И уже в сентябре стартуют два курса, где вы сможете прокачать навыки для проектов машинного обучения: MLOps для Data Science и разработки ML моделей - курс для Data Scientists & Analytics, для эффективной работы с экспериментами, моделями и подготовки production решений c FastAPI и Airflow. MLOps для Batch Scoring: автоматизация пайплайнов и CI/CD c DVC, MLflow и Airflow - курс для Machine Learning, Data и DevOps инженеров. На курсах вы научитесь:▪️ Управлять экспериментами и жизненным циклом моделей▪️ Работать с продвинутыми сценариями версионирования данных и моделей▪️ Эффективно использовать Git и следовать Git-flow в проектах▪️ Автоматизировать процессы доставки моделей в production, сборку и тестирования решений▪️ Настраивать мониторинг работы моделей и данных в production▪️ Эффективно работать с Airflow, DVD, Evidently, MLflow, FastAPI, Grafana, Git, Docker, GitLab, GitLab CI В программе курсов лекции от экспертов ML в банкинге, MedTech, AdTech, Big Data. Выбрать курс со скидкой: тут Делюсь с вами промокодом, с которым вы получите скидку 10% на любой курс: "FRIEND10" ! Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Skills for different Data scientists levels Data Science is a wide range of skills that include varying levels of knowledge and experience. The competencies required for a beginner Data Scientist will be different from those required for an experienced Data Scientist. The note is based on my observations and experience as a Head of Machine Learning and Data Science, led a team of 35+ people and 7 streams: Fintech, Devices, MobileAd and GEO, Computer Vision, NLP, Internal Projects, CVM. In this note, we will consider general skills, without delving into the specifics of NLP and Computer Vision specializations. Junior Data Scientist Let's make a small remark that we are considering mainly former trainees and graduates of universities / courses for this position. Junior Data Scientist should have the following skills: Fundamentals of Statistics and Mathematics: Linear Algebra, Probability and Statistics Python Programming Fundamentals Basic knowledge of SQL and databases: what databases are, how they are designed in theory Ability to work with Excel and other data processing tools Understanding of machine learning and algorithms such as linear regression, logistic regression and decision trees Middle Data Scientist A Middle Data Scientist should have all Junior DS skills plus the following skills: Advanced knowledge of mathematics and statistics such as optimization theory and time series Ability to work with Big Data and use Big Data tools such as Hadoop and Spark. This item is optional and depends on the company. Experience in building machine learning models, the presence of completed projects Data visualization skills and the ability to present the results of data analysis Senior Data Scientist Senior Data Scientist should have all Middle DS skills plus the following skills: Deep understanding of machine learning and algorithms Ability to create scalable and high-performance data processing systems Project and team management skills Depending on the company and the type of project, the required competencies may differ. But in general, these competencies can form the basis for the development of a Data Scientist at any level. Soft skills for Data Scientists A good Data Scientist not only has technical skills, but also has advanced soft skills. Here are the main skills that are important at different levels: Junior Data Scientist Ability to work in a team and collaborate with colleagues Possessing organizational skills to plan your tasks and manage your working time Ability to communicate complex technical information in simple language for non-specialists Middle Data Scientist Experience in mentoring junior specialists Ability to find non-standard solutions to problems Senior Data Scientist Ability to make strategic decisions and influence business results Experience in training and mentoring younger colleagues Leadership and the ability to inspire others to achieve common goals Good soft skills can help a Data Scientist achieve great results at work and move up the career ladder. They can also improve the efficiency of the team as a whole. Conclusion In the note, we reviewed the core competencies for different levels of Data Science specialists. This list of competencies can be used in your company for hiring and grading employees. ### Компетенции для разных уровней Data Scientists Data Science - это широкий диапазон компетенций, которые включают в себя различные уровни знаний и опыта. Компетенции, необходимые для начинающего Data Scientist, будут отличаться от тех, что требуются для опытного специалиста. Заметка основана на моих наблюдениях и опыте работы руководителем подразделения машинного обучения и Data Scienсе, возглавлял команду из 35+ человек и 7 стримов: Fintech, Devices, MobileAd и GEO, Компьютерное зрение, NLP, Внутренние проекты, CVM. В заметке мы рассмотрим общие компетенции, без углубления в специфику NLP и Computer Vision специализации. Junior Data Scientist Сделаем небольшую ремарку, что рассматриваем на эту позицию в основном бывших стажеров и выпускников университетов/ курсов. Junior Data Scientist должен иметь следующие компетенции: Основы статистики и математики: линейная алгебра, теория вероятности и статистика Основы программирования на Python Базовые знания SQL и баз данных: какие базы бывают, как в теории они проектируются Умение работать с Excel и другими инструментами для обработки данных Понимание машинного обучения и алгоритмов, таких как линейная регрессия, логистическая регрессия и деревья решений Middle Data Scientist Middle Data Scientist должен обладать всему компетенциями Junior DS плюс нижеперечисленные скиллы: Углубленные знания математики и статистики, такие как теория оптимизации и временные ряды Умение работать с большими данными и использовать Big Data инструменты, такие как Hadoop и Spark. Этот пункт опционален и зависит от компании Опыт в построении моделей машинного обучения, наличие реализованных проектов Навыки визуализации данных и умение презентовать результаты анализа данных Senior Data Scientist Senior Data Scientist должен обладать всему компетенциями Middle DS плюс нижеперечисленные скиллы: Глубокое понимание машинного обучения и алгоритмов Умение создавать масштабируемые и высокопроизводительные системы обработки данных Навыки управления проектами и командой В зависимости от компании и типа проекта, требуемые компетенции могут отличаться. Но в целом, эти компетенции могут служить основой для развития Data Scientist на любом уровне. Софт скиллы для Data Scientists Хороший Data Scientist не только владеет техническими навыками, но и обладает прокаченными софт скиллами. Вот основные скиллы, которые важны на разных уровнях: Junior Data Scientist Умение работать в команде и сотрудничать с коллегами Обладание организационными навыками для планирования cвоих задач и управления своим рабочим временем Умение доносить сложную техническую информацию простым языком для неспециалистов Middle Data Scientist Опыт в менторстве junior специалистов Умение находить нестандартные решения для задач Senior Data Scientist Умение принимать стратегические решения и влиять на бизнес-результаты Опыт в обучении и наставничестве более молодых коллег Лидерство и умение вдохновлять других на достижение общих целей Хорошие софт скиллы могут помочь Data Scientist достигнуть больших результатов в работе и продвинуться по карьерной лестнице. Они также могут повысить эффективность работы команды в целом. Заключение В заметке мы рассмотрели основные компетенции для разные уровней Data Science специалистов. Этот список компетенций можно использовать в своей компании для найма и грейдирования сотрудников. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### How to Become a Machine Learning Engineer First, let's define the difference between a Machine Learning Engineer and a Data Scientist. While a Data Scientist may work more on modeling and focus on the intricacies of algorithms, a Machine Learning Engineer is more likely to work on deploying the same model in a production environment that will interact with users or automate learning, monitoring, feature collection. Very often in companies, these two duties are performed by one specialist. In this article, we will look at what skills a Machine Learning Engineer needs. Demand Machine Learning Engineer in 2022 is in the top 10 highly paid professions. Salaries in the US range from $115,000 to $171,000 on average per year. Machine Learning engineers in the field of Natural Language Processing became the most sought-after specialists. Their average salary is $160,227. Source In studies of data professions in the market of Kazakhstan and Russia, unfortunately, Machine Learning Engineer and Data Scientist specialists are not separated by salary levels. Therefore, we will focus on the Data Scientist. In Kazakhstan, the average salary is 682 thousand tenge per month. More details can be found in the study. In Russia, the demand for Data Scientist grew by 93%, as for salaries, the growth was 11%. Forks of salaries for Data Scientist: for juniors 20 - 200, for middles 60 - 300, for seniors and leads from 100 - 700 thousand rubles. Read more here. Distribution of salaries by grades What does a Machine Learning Engineer do? A Machine Learning Engineer is much more likely to roll out a model to production. This skill is where machine learning engineers and data scientists differ the most. We can consider that the position of a Machine Learning Engineer is actually an engineer for the operation of machine learning models. But this is a delusion, a machine learning engineer can focus not only on operations and operation of models, but also on the operation and optimization of machine learning algorithms. While some companies prefer an all-round Data Scientist who is able to both work with machine learning algorithms and implement these solutions in production. But still, many companies will prefer to separate these two roles. It can be difficult for one person to do everything from start to finish, so having two people to build the model and one to deploy it is often a more efficient approach. What a Machine Learning Engineer Should Know Machine Learning Engineer is an engineering specialization that combines computer science and data science fields. This requires him to have knowledge of the basics of computer science, algorithms, data structures. Be able to write production and maintainable code covered with tests. At the same time, it should be taken into account that sometimes it is important for a Machine Learning Engineer to know certain areas of data science in order to build effective systems. For example: Computer Vision or Natural Language Processing. There are also many tools that are required for the job. Such as Docker, Flask, MLFlow, Airflow, FastAPI just to name a few. Separately, I will single out cloud platforms: AWS, Google Cloud, Azure. Cloud services are now extremely popular and more and more companies, projects and startups are working in the clouds. Algorithms and data structures Algorithms and data structures play a critical role in the development and optimization of machine learning systems. They are used to process and analyze large amounts of data, design ML systems and develop complex APIs. Some of the main reasons why algorithms and data structures are important to machine learning include: Efficiency: Choosing the right algorithm and data structure can greatly increase the efficiency of a machine learning model. For example, using fast sorting algorithms can significantly reduce model training time. Data complexity: Some machine learning problems can be very complex and require special algorithms and data structures. For example, text analysis can use natural language processing algorithms that are designed to work with unstructured data. Scaling: As data size grows, more efficient algorithms and data structures may need to be used. Some machine learning algorithms can be very resource intensive and do not scale well with data growth. Choosing the right data structure can help ensure model scalability. Recommend courses: Algorithms: theory and practice. Methods Algorithms: theory and practice. Data Structures Programming in Python and C++ Python and C++ are the programming languages ​​most commonly used in Machine Learning work by an engineer. What both studies confirm: Machine Learning Engineer Skills Top 25 Machine Learning Engineer Skills Python and machine learning libraries such as scikit-learn, Pytorch, and others allow developers to quickly build and train machine learning models. C++ can be used to write more optimized code and speed up machine learning models. C++ is a more complex programming language than Python, but it provides significantly better performance. This makes it a good choice for applications where performance is critical. Let's take a closer look at the benefits of C++: Performance: C++ is a compiled language, which improves performance over interpreted languages ​​such as Python. Multithreading: C++ has a wide range of libraries that can be used to create parallel applications and perform computations on multiple threads. Low-level programming: C++ allows you to have finer control over your computer's hardware resources than high-level languages ​​like Python. This allows the code to be better optimized for working with memory and other hardware resources. Reliability: C++ is a strongly typed language with static type checking. This means that it can help prevent many common programming mistakes, such as pointer misuse and array overflow. Integration: C++ can be used to write libraries that can be used from other programming languages, including Python. This allows you to use the performance and threading advantages of C++ in machine learning systems written in other programming languages. Recommend courses: Introduction to Programming (C++) C++ Programming Tools In addition to the necessary basic work skills, experience with data and software engineering tools is also required. For example: Git, Docker, Flask, MLFlow, Airflow, FastAPI. Let's take a look at some of the most popular tools: Docker: Docker is a platform for developing, delivering and running applications in containers. It can be used to create isolated environments for running machine learning models, making them easy to deploy and scale. Git and GitHub: Git is a version control system that allows you to track changes in your code. GitHub is a hosting service for Git repositories. They are both widely used for developing and collaborating on machine learning projects. FastAPI is a modern Python web framework for building fast and efficient APIs. It uses modern Python technologies such as data typing and asynchrony to create high performance web services. Airflow is a workflow management tool that can be used to schedule, monitor, and execute tasks in machine learning systems. Airflow allows you to create and run machine learning pipelines that can consist of any number of tasks. It can be used to automate processes such as model training, testing, performance evaluation, and model deployment. Recommend courses: Apache Airflow 2.2: Hands-On Course Introduction to Data Engineering: Data Pipelines Flask Mega Tutorial Docker & Kubernetes: The Practical Guide Cloud platforms Cloud services are now extremely popular and more and more companies, projects and startups are working in the clouds. Among the skills for Machine Learning, this is more often a plus for salary growth: Cloud platforms Cloud services are very useful for machine learning engineers, as they provide a ready-made infrastructure and tools for training models and deploying machine learning applications. Some of the more popular machine learning cloud services include: Amazon Web Services (AWS): AWS provides many services and tools that can be useful for machine learning, including Amazon SageMaker which provides tools for training, optimizing, and deploying models machine learning. In addition, AWS has many other services such as data storage, computing resources, databases, and so on. Microsoft Azure: A core product for ML Azure Machine Learning that helps with model training and building machine learning applications. Azure also has databases, data storage, and other services. Google Cloud Platform (GCP): Google Cloud AI Platform, a tool for training, optimizing, and deploying machine learning models. All these and other cloud services allow you to work with large amounts of data and conduct experiments with various models. They also provide high fault tolerance, scalability and security, which is important when working with sensitive data. System and ML design You need to understand how to approach the definition of business requirements. For example: load, latency, storage. And also be able to work out the architecture of projects in terms of a database, a real-time system, a load balancer, a microservice, kafka, etc. In addition to system design, special attention should be paid to the use of ML. This section covers examples of topics such as recommender building, search, fraud detection, prediction, and the like. For each category, learn the algorithmic framework, how to create real-time predictions, how to map engineers in real time, how to train models with an orchestration like Airflow. Recommend courses: Machine Learning Systems Design The System Design System Design Course Conclusion The role of Machine Learning Engineer requires knowledge of not only programming languages, but also data and software engineering tools and libraries, for example, Git, Docker, Flask, MLFlow, Airflow, FastAPI. Experience with cloud services is also required, especially Amazon Web Services, Microsoft Azure, and Google Cloud Platform. It is important to be able to work out the architecture of projects in terms of a database, a real-time system, a load balancer, microservices, Kafka, etc. ### Как стать Machine Learning Engineer Для начала давайте определимся в чем разница между Machine Learning Engineer и Data Scientist. Если Data Scientist может больше работать над моделированием и сосредотачиваются на тонкостях алгоритмов, то Machine Learning Engineer более часто работает над развертыванием той же модели в производственной среде, которая будет взаимодействовать с пользователями или на автоматизации процесса обучения, мониторинга, сбора признаков. Очень часто в компаниях эти две обязанности выполняет один специалист. В этой статье мы рассмотрим какие навыки нужны Machine Learning Engineer. Востребованность Machine Learning Engineer в 2022 году входит в топ 10 высокооплачиваемых профессий. Зарплаты в США от $115 тысяч до $171 тысячи в среднем в год. Самими же востребованными специалистами стали Machine Learning инженере в области Natural Language Processing. Их зарплата в среднем составляет 160 227 долларов США. Источник В исследованиях дата-профессий по рынку Казахстана и России к сожалению не разделяют специалистов Machine Learning Engineer и Data Scientist по уровням зарплат. Поэтому будем ориентироваться на Data Scientist. В Казахстане средняя зарплата составляет 682 тысячи тенге в месяц. Более подробно можно почитать в исследовании. В России спрос на Data Scientist вырос на 93%, что же касается зарплат то рост составил 11%. Вилки зарплат для Data Scientist: для джунов 20 - 200, для мидлов 60 - 300, для синьоров и лидов от 100 - 700 тысяч рублей. Подробнее тут. Распределение зарплат по грейдам Чем занимается Machine Learning Engineer Machine Learning Engineer гораздо чаще занимается выкаткой модели в продакшен. Именно в этом навыке больше всего различаются инженеры по машинному обучению и специалисты по обработке и анализу данных. Можно считать, что позиция Machine Learning Engineer, это на самом деле инженер по эксплуатации моделей машинного обучения. Но это заблуждение, инженер по машинному обучению может сосредоточиться не только на операционной деятельности и эксплуатации моделей, но и на работе и оптимизации алгоритмов машинного обучения. В то время как некоторые компании предпочитают всестороннего Data Scientist, который способен как работать с алгоритмами машинного обучения так и внедрять эти решения в продакшен. Но всё таки многие компании предпочтут разделить эти две роли. Одному человеку может быть сложно сделать все от начала до конца, поэтому наличие двух специалистов, один из которых занимается построением модели, а другой — ее развертыванием, часто является более эффективным подходом. Что должен уметь Machine Learning Engineer Machine Learning Engineer это инженерная специализация, которая сочетает в себя computer science и data science области. Это требует от него знаний основ computer science, алгоритмов, структур данных. Уметь писать продуктовый и поддерживаемый код покрытый тестами. При этом следует учесть, что иногда для Machine Learning Engineer важно знание отдельных областей data science для построения эффективных систем. Например: Computer Vision или Natural Language Processing. Существует также множество инструментов, которые необходимы для работы. Такие как Docker, Flask, MLFlow, Airflow, FastAPI и это лишь некоторые из них. Отдельно выделю облачные платформы: AWS, Google Cloud, Azure. Облачные сервисы сейчас крайне популярны и всё больше компаний, проектов и стартапов работают в облаках. Алгоритмы и структуры данных Алгоритмы и структуры данных играют критически важную роль в разработке и оптимизации систем машинного обучения. Они используются для обработки и анализа больших объемов данных, проектирование ML систем и разработку сложный API. Некоторые из основных причин, по которым алгоритмы и структуры данных являются важными для машинного обучения, включают в себя: Эффективность: Выбор правильного алгоритма и структуры данных может существенно повысить эффективность модели машинного обучения. Например, использование быстрых алгоритмов сортировки может значительно сократить время обучения модели. Сложность данных: Некоторые задачи машинного обучения могут быть очень сложными и требуют специальных алгоритмов и структур данных. Например, для анализа текста могут использоваться алгоритмы обработки естественного языка, которые предназначены для работы с неструктурированными данными. Масштабирование: С ростом размера данных может потребоваться использование более эффективных алгоритмов и структур данных. Некоторые алгоритмы машинного обучения могут быть очень ресурсоемкими и не масштабируются хорошо с ростом количества данных. Выбор правильной структуры данных может помочь в обеспечении масштабируемости модели. Рекомендую курсы: Алгоритмы: теория и практика. Методы Алгоритмы: теория и практика. Структуры данных Программирование на Python и C++ Python и C ++ являются языками программирования, которые наиболее часто используются в работе Machine Learning инженером. Что подтверждают оба исследования: Навыки Machine Learning инженера Топ 25 навыков Machine Learning инженера Python и библиотеки машинного обучения, такие как scikit-learn, Pytorch и другие, позволяют разработчикам быстро создавать и обучать модели машинного обучения. C++ же можно использовать для написания более оптимизированного кода и ускорения работы моделей машинного обучения. C++ более сложный языком программирования, чем Python, но он обеспечивает значительно более высокую производительность. Это делает его хорошим выбором для решений, где производительность играет важную роль. Остановимся чуть более подробно на преимуществах C++: Быстродействие: C++ является компилируемым языком, что повышает производительность по сравнению с интерпретируемыми языками, такими как Python. Многопоточность: C++ обладает широким набором библиотек, которые могут использоваться для создания параллельных приложений и выполнения вычислений в нескольких потоках. Низкоуровневое программирование: C++ позволяет иметь более тонкий контроль над аппаратными ресурсами компьютера, чем высокоуровневые языки, такие как Python. Это позволяет лучше оптимизировать код для работы с памятью и другими аппаратными ресурсами. Надежность: C++ - это язык со строгой типизацией и статической проверкой типов. Это означает, что он может помочь предотвратить многие типичные ошибки программирования, такие как неправильное использование указателей и выход за пределы массивов. Интеграция: C++ может использоваться для написания библиотек, которые могут быть использованы из других языков программирования, в том числе из Python. Это позволяет использовать преимущества C++ в производительности и многопоточности в системах машинного обучения, написанных на других языках программирования. Рекомендую курсы: Введение в программирование (C++) Программирование на языке C++ Инструменты Кроме необходимых базовых навыков работы, так же требуется опыт работы с инструментами data и software инжиринга. Например: Git, Docker, Flask, MLFlow, Airflow, FastAPI. Остановимся на одних самых популярных инструментах: Docker: Docker - это платформа для разработки, доставки и запуска приложений в контейнерах. Он может быть использован для создания изолированных сред для запуска моделей машинного обучения, что облегчает их развертывание и масштабирование. Git и GitHub: Git - это система управления версиями, которая позволяет отслеживать изменения в коде. GitHub - это хостинг-сервис для Git-репозиториев. Они оба широко используются для разработки и совместной работы над проектами машинного обучения. FastAPI - это современный веб-фреймворк для Python, предназначенный для создания быстрых и эффективных API. Он использует современные технологии Python, такие как типизация данных и асинхронность, для создания высокопроизводительных веб-сервисов. Airflow - это инструмент для управления рабочим процессом, который может использоваться для планирования, мониторинга и выполнения задач в системах машинного обучения. Airflow позволяет создавать и запускать пайплайны машинного обучения, которые могут состоять из любого количества задач. Он может быть использован для автоматизации процессов, таких как обучение моделей, тестирование, оценка производительности и развертывание моделей. Рекомендую курсы: Apache Airflow 2.2: практический курс Введение в Data Engineering: дата-пайплайны Мега-Учебник Flask Docker & Kubernetes: The Practical Guide Облачные платформы Облачные сервисы сейчас крайне популярны и всё больше компаний, проектов и стартапов работают в облаках. Среди навыков для Machine Learning это чаше является плюсом для роста заработной платы: Облачные платформы Облачные сервисы очень полезны для machine learning инженеров, так как они предоставляют готовую инфраструктуру и инструменты для обучения моделей и развертывания приложений машинного обучения. Некоторые из наиболее популярных cloud-сервисов для машинного обучения включают в себя: Amazon Web Services (AWS): AWS предоставляет множество услуг и инструментов, которые могут быть полезны для машинного обучения, включая Amazon SageMaker, который предоставляет средства для обучения, оптимизации и развертывания моделей машинного обучения. Кроме того, в AWS есть множество других сервисов, таких как хранилище данных, вычислительные ресурсы, базы данных и т.д. Microsoft Azure: основной продукт для ML Azure Machine Learning, который помогает в обучении моделей и создания приложений машинного обучения. У Azure также есть базы данных, хранилище данных и другие сервисы. Google Cloud Platform (GCP): Google Cloud AI Platform, инструмент для обучения, оптимизации и развертывания моделей машинного обучения. Все эти и другие облачные сервисы позволяет работать с большими объемами данных и проводить эксперименты с различными моделями. Они также обеспечивают высокую отказоустойчивость, масштабируемость и безопасность, что является важным при работе с конфиденциальными данными. System и ML design Необходимо понимать, как подходить к определению бизнес-требований. Например: нагрузка, задержка, хранилище. А так же уметь прорабатывать архитектуру проектов с точки зрения базы данных, системы реального времени, балансировщика нагрузки, микросервиса, kafka и т. д. Кроме системного дизайн нужно особое внимание уделять применению ML. В этом разделе рассматриваются примеры таких тем, как создание системы рекомендаций, поиск, обнаружение мошенничества, прогнозирование и тому подобное. По каждой категории изучите алгоритмическую структуру, как создавать прогнозы в режиме реального времени, как отображать инженеров в режиме реального времени, как обучать модели с помощью оркестровки, такой как Airflow. Рекомендую курсы: Machine Learning Systems Design The System Design System Design Course Вывод Для роли Machine Learning Engineer требуется знания не только языков программирования, но и инструментов и библиотек data и software инжиринга, например, Git, Docker, Flask, MLFlow, Airflow, FastAPI. Также необходим опыт работы с облачными сервисами, особенно Amazon Web Services, Microsoft Azure и Google Cloud Platform. Важно уметь прорабатывать архитектуру проектов с точки зрения базы данных, системы реального времени, балансировщика нагрузки, микросервисов, Kafka и т.д. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Конспект книги «Правила магической пирамиды для делового письма» Аннотация Эта книга учит составлять письменные документы и устные выступления. Согласно теории автора, текст делового документа хорошо воспринимается только в том случае, если его идеи логически взаимосвязаны и выстроены по принципу пирамиды. Только такая структура делает сообщение максимально доступным для понимания, потому что мысли излагаются в порядке, оптимальном для восприятия. Эта теория прошла проверку временем: автор много лет преподает свой курс в крупнейших бизнес-школах, университетах и компаниях Европы и США. «Золотые правила Гарварда и McKinsey» необходимы всем, кому приходится иметь дело с составлением отчетов, служебных записок, докладов, выступлений, презентаций, а также всем, кто хочет научиться предельно ясно и правильно излагать свои мысли, вне зависимости от рода деятельности. Барбара Минто «Золотые правила Гарварда и McKinsey. Правила магической пирамиды для деловогописьма» Издательство: "Манн, Иванов и Фербер", — 2007 Купить цифровую книгу в books.ru, бумажную книгу в FLIP или Лабиринте. Введение Книга повествует о том, как использовать принцип магической пирамиды, чтобы писать ясные и понятные деловые документы: Определить цель, главную мысль, которую вы хотите донести до читателя Изложить эту мысль в словах или письменно Принцип магической пирамиды — принцип написания текста, исходя из требований логики и объективно ограниченных возможностей читателя в восприятии больших объемов информации.Книга расскажет как: пользоваться правилами магической пирамиды в процессе обдумывания документа использовать полученные знания, чтобы критически анализировать структуру документа, какустранить логические ошибки и сделать процесс осмысления более творческим ипродуктивным Посмотрим на текст ниже:«Джон Коллинз звонил, чтобы передать, что он не сможет присутствовать на встрече в 3.00. Хэл Джонсон сообщил, что не рассчитывает быть раньше, а то и вовсе завтра, но не раньше 10.30. А секретарь Дона Клиффорда передала, что Клиффорд вернется из Франкфурта не раньше чем завтра, а то и позже. Конференц-зал завтра занят, но свободен в четверг. Так что четверг 11.00 был бы самым подходящим временем для встречи. Устраивает ли это вас?». Автор этой записки сделал именно то, что делает большинство людей, когда пишет. Он воспользовался процессом письма как средством, которое помогло ему наконец-то сформулировать свои соображения. Действительно, письменное изложение как способ организовать процесс обдумывания - вполне подходящий инструмент. Но в результате вы перекладываете часть груза на плечи читателя, заставляете его пробираться сквозь несколько незначащих высказываний, прежде чем он придет вместе с вами к итоговому заключению. Насколько легче стало бы запутавшемусяадресату, если бы он мог прочитать:«Не могли бы мы перенести сегодняшнюю встречу на четверг, на 11.00? Это время полностью устраивает Коллинза и Джонсона, а также позволит присутствовать на встрече Клиффорду». Идеи в презентации или документе должны выстраиваться в форме пирамиды. Главная мысльнаходится на вершине пирамиды. Правила магической пирамиды для делового письма От идеи к структуре. Порядок осмысления от частного к главному На самом низком уровне пирамиды вы группируете высказывания, каждое из которых содержит какую-то частную идею, в параграфы. Предположим, вы объединяете в одном параграфе шесть высказываний. Причина, по которой объединены эти шесть, а не другие, будет только одна, а именно: вы отчетливо понимаете логическую взаимосвязь между ними. И эта логическая взаимосвязь будет присутствовать всегда, так как без нее не выразить общую идею параграфа, эффективно суммирующую идеи отдельных высказываний. Не стоит, например, объединять пять высказываний о финансах и одно - о теннисе, потому что будет трудно показать значимость и уместность каждого суждения. Вам будет трудно формулировать одно суммирующее, подытоживающее смысл параграфа высказывание. Формулируя общий смысл параграфа, вы поднимаетесь вверх на один уровень абстракции. Теперь вы можете воспринимать параграф как обобщенное высказывание, содержащее одну мысль, а не шесть. Это позволяет вам объединить в группы, скажем, три параграфа. Ведь каждый из них содержит одну-единственную мысль, пусть и на более высоком уровне абстракции, чем составляющие его отдельные высказывания. Основная причина, по которой вы объединяете в раздел эти, а не другие параграфы, заключается в следующем: вы видите логическую взаимосвязь именно этих параграфов. И без нее вы не сможете выразить единую общую идею раздела, эффективносуммирующую идеи отдельных параграфов. Объединять идеи в группы нужно, руководствуясь следующими правилами: На каждом уровне пирамиды идеи всегда должны резюмировать идеи, объединенные уровнем ниже; Идеи в каждой группе всегда должны быть одного вида. Так, если первая идея - это причина какого-то действия, то вторая идея в этом параграфе или разделе также должна быть причиной для того же самого действия. Если первая идея - это этап какого-то процесса, остальные идеи, принадлежащие этой группе, должны быть этапами того же самого процесса. Если первая идея - это проблема в компании, другие тоже должны быть связаны с проблемами компании и так далее. Идеи в каждой группе всегда должны быть логически упорядочены: дедуктивный (большая посылка, малая посылка, вывод), хронологический (первое, второе, третье), структурный (Алматы, Астана, Атырау), классификационно-сравнительный (первый по значимости предмет,второй по значимости предмет и т. д.). Вернейший способ убедиться, верно ли вы объединили идеи в группу, - попробовать обобщить их. Для этого воспользуйтесь как ярлыком существительным во множественном числе или собирательным существительным. Вы обнаружите, что идеи, которые можно объединить, можно и назвать общими словами: рекомендации, причины, проблемы, изменения. Не существует каких-либо иных ограничений на объединение различных идей в группы. Помните только одно: это всегда и обязательно множество идей одного и того же вида и их можно обобщить одним существительнымво множественном числе. Как убедиться в том, что вы верно объединяете идеи в группы, будет объяснено во второй части книги, главах седьмой, восьмой и девятой. Другими словами, всегда должно существовать объяснение тому, почему вторая идея идет именно второй и не может быть ни первой, ни третьей. Порядок, который вы выбираете, отражает аналитические процессы, использованные вами при объединении идей в группы. Если вы руководствовались дедуктивными основаниями, идеи идут в порядке логических аргументов. Если использовали причинно-следственную связь, то в хронологическом порядке. Если высказывались о существующей структуре, то порядок диктуется именно ею. Если классифицировали, то - порядком значимости. Поскольку эти четыре вида — дедуктивные умозаключения, выявление причинно-следственных связей, разделение целого на части и классификация - охватывают все возможные виды аналитической деятельности, на которуюспособен разум, то и способов упорядочения любых идей существует только четыре. Принципиально важно понимать, что еще до того, как вы начнете писать, необходимо выстроить свои идеи в форме пирамиды. Проверить, соответствует ли ваша пирамида правилам. Если вдруг какое-то из этих правил нарушено, значит, вы не точны в своих размышлениях или не развили и не обосновали свои идеи до конца. А возможно, что связали их, таким образом, который помешает читателю найти вложенный в них первородный смысл. Найдя ошибки, вы сможетепереработать идеи. Затем очистить свои суждения, выстроить структуру документа в соответствии с правилами. Это избавит вас от необходимости обширных изменений, переделок и переписывания документа в дальнейшем. Архитектура пирамиды - Горизонтальные взаимосвязи Группа идей, объединенных дедуктивными взаимосвязями, представляет аргументы последовательно. То есть первое положение содержит некое высказывание о ситуации, которая существует в мире сегодня. Второе уточняет объект (тему) или предикат высказывания, а в третьем связываются два первых положения. Так, идеи, объединенные в группу, могут быть поданы так: человек смертен, Сократ - человек, следовательно, Сократ смертен В индуктивной группе идеи, напротив, связаны только наличием какой-то общей черты или отношением к факту. Такие идеи, как правило, могут быть обобщены одним существительным во множественном числе или собирательным существительным (доводы за, возражения против, шаги, проблемы и т.д.). Примерная форма построения индуктивных аргументов может быть такой: французские танки у польской границы, немецкие танки у польской границы, русские танки у польской границы. Чтобы подняться на один уровень абстракции выше над группой с дедуктивными связями, вы резюмируете, акцентируя, подчеркивая заключительное положение: «Так как Сократ - человек, он смертен». Здесь, для того чтобы подняться на уровень абстракции выше, вы строите свой вывод на утверждении, родственном для всех трех суждений. Ищете то, что их может объединить. В нашем примере это какие-то военные приготовления против Польши. Тогда вывод будет примерно таким: «Польша накануне танкового вторжения». Итак, когда вы пишете и отвечаете на вопрос, используя дедуктивную аргументацию, вы должны: во втором суждении комментировать объект (тему) или предикат* (информацию) первого суждения, а в третьем суждении строить вывод, исходя из первых двух. Если вы используете индуктивные обоснования, вы объединяете идеи в группу на основе их логического сходства. Помните об обязательной необходимости описать их существительным во множественном числе. Начинаем строить пирамиду - Способ строительства «сверху вниз» Способ строительства «сверху вниз» Заполните верхний блок пирамиды. Что именно вы обсуждаете? На какой вопрос о теме (объекте),стоящий перед читателем, вы отвечаете? Каков ваш ответ? Сформулируйте и уточните вопрос для вступления. Какова ситуация? Что за трудности? Сформулированы ли вопрос и ответ на него? Определите линию ключевых утверждений. Какой новый вопрос порождается вышестоящим ответом? Индуктивно или дедуктивно вы будете отвечать на него? Если индуктивно, то каким будет объединяющеесуществительное во множественном числе? Структурируйте поддерживающие соображения. Повторите процесс вопрос/ответ на этом уровне. Обычно садясь за стол писать, вы обнаруживаете, что только приблизительно знаете, о чем хотите рассказать. Но что именно и каким образом - для вас проблема. Эта неопределенность значительно увеличивает трудности построения ясной структуры. Как строить ее в форме пирамиды? Ответ подсказывает сама структура. Она помогает вам, а не усложняет работу. Имея представление о ней, вы уже точно знаете, как должен выглядеть документ, и, следовательно, можете егопланировать. Достоинства хорошего Введения Во введении следует рассказывать историю. Достоинства хорошего Введения С чего начинать описание ситуации? Вы начинаете описание ситуации с суждения о предмете, с которым читатель, на ваш взгляд, согласится, потому что вы рассказываете ему нечто известное. Если вы вдруг обнаружите, что не можете высказать такое суждение о предмете, значит, вы выбрали или неправильную тему изложения, или начинаете рассуждения не с того места. Вы рискуете спугнуть или вовсе потерять читателя. Определение линии ключевых утверждений в начале документа. Описание ситуации Проблема во Введении - это не житейская трудность в обычном смысле этого слова. Она является таковой только в нашем рассказе о ситуации. Чаще всего она описывает альтернативустабильному положению, а не суть затруднения саму по себе. Что такое проблема? СИТУАЦИЯЗАТРУДНЕНИЕВОПРОСОбнаружена стабильная ситуацияНечто идет неправильноНечто может пойти неправильноЧто нам делать?Как мы можем предотвратить это?Нечто изменилосьЧто нам следует делать?Нечто может изменитьсяКак нам следует реагировать?Вот то, что мы могли бы ожидатьМы ожидали этого?Существуют иные точки зренияКто прав?В этом положении мы имеем три альтернативыЧто нам выбрать?Проблема Дедуктивное обоснование - Как используется Дедуктивно выстроенные суждения - конструкции, состоящие из трех обязательных положений: Некое утверждение, заключающее в себе информацию о ситуации в мире Еще одно утверждение, заключающее в себе информацию о ситуациив мире, следующей из первого положения. Второе положение будет связано с первым, если будет пояснять или комментировать его субъект илипредикат Вывод, в котором обосновывается следствие из информации об этих двухситуациях, существующих в мире в одно и то же время Дедуктивное обоснование Дедуктивное обоснование - Когда можно и нужно пользоваться дедукцией Давайте разберемся в том, какую работу совершает читатель, если вы вынуждаете его воспринимать дедуктивные рассуждения на ключевой линии. Допустим, вы хотите убедить его в необходимости предпринять какие-то изменения: Дедуктивное обоснование - Когда можно и нужно пользоваться дедукцией Чтобы воспринять вашу мысль, читатель должен по порядку оценить всю подкрепляющую цепочку доводов А1-В1-С1 из подробного описания проблемной ситуации, причем в определенном порядке дедуктивного рассуждения. Как организовать и «высветить» структуру документа – Заголовки Важным техническим приемом для организации структуры при помощи заголовков является субординация заголовков, отражающая субординацию идей. Такая субординация устанавливается расстоянием заголовка or левого поля документа. Главные заголовки примыкают к полю, подзаголовки сдвигаются вправо, названия параграфов сдвигаются еще правее и т. д. Конечно же, такой логике должен соответствовать и визуальный стиль заголовков, то есть размер и толщина шрифта. И вновь напомним: каждый заголовок должен соответствовать определенной целостной группе суждений. Поскольку заголовки представляют группы суждений, они должны отражать и взаимосвязь между идеями внутри пирамидальной структуры. Вот некоторые правила для распределения заголовков. Как организовать и «высветить» структуру документа Вывод На самом деле в книге очень много воды. Самое полезное можно найти в первых четырех главах. В принципе в конспекте я постарался отразить наиболее интересное и важное. Прочитать нужно обязательно! Ради первых четырех глав. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Конспект книги «Кратко. Ясно. Просто» Аннотация В книге аргументировано излагается представление авторов о том, что практически все сферы современной жизни - бизнес, госуправление, образование, медицинское обслуживание - регулируются чрезмерно усложненными процедурами, правилами и документацией. Авторы показывают, как усложненность отнимает время, вынуждает к лишней трате средств и подрывает доверие к социальным институтам общества. Наоборот, ориентация на удобство клиента, ясность правил и прояснение смыслов в любой сфере деятельности позволяет завоевать доверие клиентов, сэкономить средства и повысить качество услуг. Книга поможет всем, кто стремится к эффективности, созданию более комфортных условий жизни и повышению уровня доверия в обществе. Алан Сигел, Айрин Этцкорн «Кратко. Ясно. Просто» Издательство: "Олимп-Бизнес" — 2015 Купить цифровую книгу в ЛитРес , бумажную книгу в FLIP, Ozon или Лабиринте. Основные тезисы книги Усложнение наносит ущерб бизнесу, правительству и финансам - в 1980 году типовой договор на использование кредитной карты умещался на полутора страницах. Сегодня он разросся до 31страницы. В результате люди больше не вчитываются в эти соглашения. Позже они с удивлением обнаруживают, что их счета аннулированы или процентные ставки по кредиту слишком высоки. Простота труднодостижима - требуется немало усилий, чтобы организовать, оптимизировать,прояснить и ощутить окружающий мир. Сложность как способ монетизации – многие компании намеренно создают сложности. Банки,кредитные организации, страховые зарабатывают на мелком шрифте. Сложности используют как щит - чтобы избежать судебных исков и других потенциальныхпроблем, юристы придумали огромное количество оговорок, данных, не подлежащих разглашению,условий, инструкций, поправок и поправок к поправкам. Больше информации – не больше ясности - следы эпидемии «сверхобъяснений» можно найтивезде: от руководства по работе суда присяжных до инструкции по эксплуатации какого-нибудьприбора Кейс - больница Едва ли можно найти места более хаотичные, чем больницы. Это делает их идеальными лабораториями для тестирования стратегий упрощения. Сегодня такие медицинские центры, как Mayo Clinic, Kaiser Permanente и Cleveland Clinic, находятся среди пионеров, ищущих способы оптимизации некоторых специализированных вопросов. Взаимодействие между медицинскими сестрами - пересменка в больницах приводит к перебоям в непрерывности ухода за пациентами. В клинике Kaiser Permanente разработали простой протокол для обмена информацией между сестрами у койки пациента (в этом также может участвовать и сам больной), что уменьшило путаницу и непонимание. Способ, при помощи которого хирурги отслеживают этапность процесса лечения - некоторые клиники позаимствовали у авиаторов и адаптировали к своим нуждам чек-листы, впервые разработанные в авиакомпании Boeing. Списки контрольных вопросов теперь используются во время хирургических операций – в них указаны последовательность и перечень действий и процедур, которые должны быть обязательно выполнены. Перечень услуг, предлагаемых больницами - некоторые клиники поступают подобно ритейлерам, находящим преимущества в товарной специализации. Они оказывают услуги в определенной узкой сфере. Если пациенту нужно загипсовать локоть, его отправят в конкретное лечебное учреждение, если же требуется проверить сердце – примут в другом месте. Эмпатия Упрощение – это стремление уменьшить дистанцию, которая обычно существует между компанией и клиентом, госпиталем и пациентом, правительством и гражданином. Все начинается с желания понять обстоятельства и потребности другой стороны. Лучше понимая потребности, вы можете принимать обоснованные решения как бы от имени других. Упрощать – это помогать и вносить коррективы, чтобы отсеять лишние варианты и избавить клиента от разрушительных «мук выбора» Неявные точки взаимодействия В идеале все, что делает компания по отношению к клиентам – сообщает о продуктах и услугах в письмах, разрабатывает веб-сайт или отправляет счета, – должно отражать готовность встать на их точку зрения. Взаимодействуя с разными предприятиями, каждый из нас ожидает, что к нему отнесутся по-человечески. И это на самом деле не сложно: у любой компании есть множество возможностей и способов показать потребителю, что она и есть та самая организация, котораяуважает его интересы. Нас всегда поражает, что компании тратят миллионы на создание брендов, а затем разрушают их одним росчерком пера. Дело в том, что любая корреспонденция, отправляемая клиентам: переписка по электронной почте, информационное письмо, договор, предложение, инструкция, форма заявки или распечатка из колл-центра, – «говорит» о предприятии громче любой рекламы. Ведь все это – самая прямая и личная форма контакта. Каждая из таких неявных точек взаимодействия должна считаться «тревожной кнопкой» – как будто именно она и есть судьбоносный момент вовзаимоотношениях с клиентами. Всякий подобный контакт следует настраивать под конкретного потребителя таким образом, чтобы любой тип общения отражал атрибуты и качества бренда. Неявные точки взаимодействия Здесь работает интересный «круговой эффект». Договоры купли-продажи, страховые полисы, юридические соглашения и инструкции по использованию продуктов часто бывают настолько запутанны, что обычно люди их не читают. В свою очередь компании решают: незачем тратить время и деньги на прояснение сути – ведь все равно клиентов это не волнует. Постепенно в таких организациях к рутинным коммуникациям начинают относиться небрежно, считая их «необходимымзлом» и «канцелярщиной». Бывает, что эту работу поручают программистам и юристам, которые что- то меняют в бумажках и сообщениях, но не стремятся их переделать. Все заканчивается тем, что на свет появляются документы и веб-сайты с многословным, неорганизованным, неточным и избыточным наполнением. Здесь заключена серьезная проблема для бизнеса: ведь ядро неявных точек взаимодействия формируется в результате ежедневных контактов с клиентами. В конце концов они превращаются в регулярно упускаемые возможности. Что происходит в итоге? Клиенты уходят. Тем предприятиям, которые заявляют «С нами легко иметь дело», полезно проверить это на собственном опыте. Уделяйте внимание каждому контакту, даже самому незначительному. Наиболее успешные организации создают продукты и услуги совместно с клиентами и интегрируют их в основные процессы. Они внедряют новые каналы для привлечения клиентов, чтобы оставаться с ними в гармонии. Благодаря картине из более глубоких данных успешные руководители считают близость с клиентом приоритетом номер один. Лучшие исполнители управляют сложностью от имени своих организаций, клиентов и партнеров. Они добиваются этого путем упрощения операций и продуктов, а также за счет гибкого разнообразия способов работы, доступа к ресурсам и освоения новых рынков по всему миру. Благодаря этому, в отличие от обычных руководителей, эффективные бизнес-лидеры ожидают в будущем 20-процентного роста доходов. Вывод Книга очень понравилась, рекомендую! В ней собрано огромное количество примеров и советов. К сожалению в рамках конспекта все это описать не реально. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Model deployment with Google Cloud Functions In this note, I will tell you how to deploy a model for free up to a certain level of use and not bother with writing a microservice. I note that such a solution is easily integrated, for example, into a web service. All you need is to use Google Cloud Functions. Google Cloud Functions is a serverless approach, i.e. server services are provided without renting or purchasing equipment. With this approach, the provider manages infrastructure resources, configures and maintains them. The main advantage of Google Cloud Functions is automatic scalability, high availability and fault tolerance. Prices Google Cloud Functions pricing depends on how long your function runs, how many times it is called, and how much resources you allocate to that function. If your function makes an outgoing network request, there is also an additional data transfer charge. But most importantly, Google Cloud Functions includes a lifetime free calling tier so you can experiment with the platform for free. From myself, I can say that for MVP and small projects, the free plan is more than enough. Price table: Сalls per monthPrice/mln.First 2 millionFreeOver 2 million$0.40Prices for accessing Google Cloud Functions Calculation time Computation time is measured from the time your function receives a request to the time it completes, either through a completion signal, or through a timeout, another failure, or any other termination. Computation time is measured in 100 ms increments and rounded up to the nearest increment. For example, a function that runs for 260ms will be billed as 300ms. More details can be found in the official documentation. Usage example For one project, I had the task of determining its category by the text of a vacancy. For example: BACKEND, FRONTEND, MOBILE DEV, DESIGN, PRODUCT, DA/DS and others. CatBoostClassifier was trained as a model. Average ROC AUC Model 0.979 Confusion Matrix on validation: model confusion matrix This is the model we will deploy using Google Cloud Functions. Setting up Google Cloud Functions Go to google cloud console and click create function Environment select 2nd gen. We give the name of our function, for example: model1. In Authentication, select Allow unauthenticated invocations. We click on Next. Setting up Google Cloud Functions Then, to use the Python libraries, we need to register 8080 PORT in the tab Runtime, build, connections and security settings → BUILD Runtime, build, connections and security settings Next, you have two options to write the code for your Google Cloud Function: In the Code tab, you can select Inline editor. And there write the code of your function and specify it as an Entry Point. You can download the entire code in zip format. And specify the Entry Point as well. I prefer the second option, it's much easier and faster. In the code, you should pay attention to 3 things: Use functions_framework library Use @functions_framework.http decorator for your function Entry Point It's better not to specify library versions in requirements.txt Code Example: @functions_framework.http def main(request): text = request.args.get('vactext') corpus = remove_links_and_quotes(text) corpus = ' '.join(re.split('\W+', corpus.lower())) corpus = tokenize_me(corpus) Then click Deploy. If everything is in order, your service will be raised. You need to refer to it by URL. Deploy Google Cloud Function In my case, the function uses vactext with a description of the vacancy, and the category of the vacancy is returned. Call Google Cloud Function Conclusion Google Cloud Function is a service that makes it easy to deploy simple functions. The entire feature deployment process can be completed in less than 1 hour, making it a good tool for MVP work or for a feature that doesn't need many hits. Additional material https://cloud.google.com/functions ### Деплой модели с Google Cloud Functions В заметке я расскажу как до определенного уровня использования бесплатно задеплоить модель и на заморачиваться с написанием микросервиса. Отмечу, что такое решение легко интегрируется, например, в веб-сервис. Всё, что вам нужно это использовать Google Cloud Functions. Google Cloud Functions это serverless подход, т.е. серверные услуги предоставляются без аренды или покупки оборудования. При таком подходе управлением ресурсами инфраструктуры, её настройкой и обслуживанием занимается провайдер. Основной плюс Google Cloud Functions это автоматическая масштабируемость, высокая доступность и отказоустойчивость. Цены Цены на Google Cloud Functions зависят от того, как долго работает ваша функция, сколько раз она вызывается и сколько ресурсов вы выделяете для этой функции. Если ваша функция делает исходящий сетевой запрос, также взимается дополнительная плата за передачу данных. Но самая важное, что Google Cloud Functions включает бессрочный бесплатный уровень для вызовов, чтобы вы могли бесплатно экспериментировать с платформой. От себя могу отметить, что для MVP и небольших проектов бесплатного тарифа хватает с головой. Таблица с ценами: Вызовов в месяцЦена/млн.Первые 2 миллионаБесплатноБолее 2 миллионов0,40 доллара СШАЦены на обращение к Google Cloud Functions Время вычислений Время вычислений измеряется с момента, когда ваша функция получает запрос, до момента его завершения, либо через сигнал о завершении, либо через тайм-аут, другой сбой или любое другое завершение. Время вычислений измеряется с приращением в 100 мс и округляется до ближайшего приращения. Например, функция, выполняющаяся в течение 260 мс, будет оплачиваться как 300 мс. Более подробно можно почитать в официальной документации Пример использования Для одного проекта у меня была задача определять по тексту вакансии её категорию. Например: BACKEND, FRONTEND, MOBILE DEV, DESIGN, PRODUCT, DA/DS и другие. В качестве модели обучен CatBoostClassifier. Средний ROC AUC модели 0.979 Confusion Matrix на валидации: model confusion matrix Вот именно эту модель мы и будем деплоить с использованием Google Cloud Functions. Настройка Google Cloud Functions Переходим в google cloud console и нажимаем create function. Environment выбираем 2nd gen. Даём имя нашей функции, например: model1. В Authentication, выбираем Allow unauthenticated invocations. Кликаем по Next. Настройка Google Cloud Functions Затем для использования библиотек Python нам надо прописать 8080 PORT во вкладке Runtime, build, connections and security settings → BUILD Runtime, build, connections and security settings Дальше у вас есть два варианта написать код для вашей Google Cloud Function: Во вкладке Код можно выбрать Inline editor. И там написать код вашей функции и указать её как Entry Point. Можно загрузить весь код в формате zip архива. И указать так же Entry Point. Я предпочитаю второй вариант, он гораздо проще и быстрее. В коде стоит обратить внимание на 3 вещи: Использовать библиотеку functions_framework Использовать декоратор @functions_framework.http для вашей Entry Point функции Лучше не указывать версии библиотек в requirements.txt Пример кода @functions_framework.http def main(request): text = request.args.get('vactext') corpus = remove_links_and_quotes(text) corpus = ' '.join(re.split('\W+', corpus.lower())) corpus = tokenize_me(corpus) После чего кликните Deploy. Если всё в порядке ваш сервис будет поднят. Обратить к нему нужно по URL. Deploy Google Cloud Function В моём случае в функции используется vactext с описанием вакансии, а возвращается категория вакансии. Вызов Google Cloud Function Заключение Google Cloud Function — это сервис, упрощающий процесс развертывания простых функций. Весь процесс развертывания функции можно выполнить менее чем за 1 час, что делает его хорошим инструментом для работы с MVP или для функцией, где не требуется много обращений. Дополнительный материал https://cloud.google.com/functions Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Calculating Monthly Recurring Revenue (MRR) in Python What is Monthly Recurring Revenue? Monthly Recurring Revenue - regular monthly income. This metric is used primarily in subscription models. In this case, the income itself must be reduced to months. Why is it valuable? If we have a subscription service, we have regular or periodic payments, then we can understand how much money we will earn and how effective our business is. Further, we can increase MRR by switching customers to a more expensive tariff or try to reduce customer churn. The problem For this task, use the new dataset: https://alimbekov.com/wp-content/uploads/2021/03/mrr.csv Structure: customer_id - already familiar customer ID first_order - Subscription start date EndDate - Subscription end date rate - subscription plan (monthly, semi-annual, annual) Amount - amount paid commission - payment system commission We will use the following formula to calculate MRR: MRR = new + old + expansion + reactivation - churn - contraction new MRR - the first payment of a new client old MRR - recurring customer payment expansion MRR - increase in MRR due to the new tariff contraction MRR - decrease in MRR due to the new tariff churn MRR — MRR outflow due to termination of payment reactivation MRR - return of a client who had an outflow of MRR Implementing Monthly Recurring Revenue (MRR) Calculation in Python import pandas as pd import numpy as np import warnings warnings.filterwarnings("ignore") import seaborn as sns import matplotlib import matplotlib.pyplot as plt import matplotlib.ticker import matplotlib as mpl pd.set_option('max_columns', 50) mpl.rcParams['lines.linewidth'] = 2 %matplotlib inline sns.set_context( "notebook", font_scale = 1.5, rc = { "figure.figsize" : (30, 30), "axes.titlesize" : 18 } ) df_mrr = pd.read_csv('mrr.csv') We import all the necessary libraries and read the file. Let's now do some necessary calculations for further work. Let's bring all the dates to the required format, calculate the subscription duration, extract the month and year from the subscription date, calculate the amount minus the commission (the commission is 5% everywhere) and find out the amount we receive per month. df_mrr['first_order'] = pd.to_datetime(df_mrr['first_order']) df_mrr['EndDate'] = pd.to_datetime(df_mrr['EndDate']) df_mrr['Period'] = (df_mrr.EndDate.dt.to_period('M').astype(int) - df_mrr.first_order.dt.to_period('M').astype(int)) df_mrr['mmr_period'] = pd.to_datetime(df_mrr['first_order']).dt.to_period('M') df_mrr['price_after_commission'] = df_mrr['Amount']*0.95 df_mrr['Amount_per_month'] = df_mrr['price_after_commission']/df_mrr['Period'] print(df_mrr.head(2)) Таблица для расчета MMR The next step is to create a list of all unique periods. periods = df_mrr.mmr_period.sort_values(ascending=True).unique().astype(str).tolist() We are now ready to calculate MMR. The main idea is to calculate the amount taking into account the end and start dates of the subscription. In this way, we will spread the entire payment over the subscription period. mrr=[] for mdate in periods: my_df = df_mrr[(df_mrr['EndDate'].dt.to_period('M')>mdate ) & (df_mrr['first_order'].dt.to_period('M')<= mdate)] mmrr = my_df['Amount_per_month'].sum() mrr.append({'date':mdate,'mmrr':mmrr}) Let's visualize what we've got. dates = [x['date'] for x in mrr] y = [x['mmrr'] for x in mrr] sns.set() plt.figure(figsize=(40,10)) plt.title('MRR by month') plt.ylabel('total') plt.bar(dates, y) plt.rc('font',**{'family' : 'normal', 'weight' : 'bold', 'size' : 60}) plt.show() MMR Visualization We see that we have a fairly good product. MMR grew steadily until April, then the growth rate slowed down slightly, and in September we see a fall. Subscriptions began to end, and there were no more new ones. Calculation check Let's do a little visual check of the MMR calculation. Take one customer customer_id = 084a0e74918bd829d509441c2504135e test_df = df_mrr[df_mrr.customer_id=='084a0e74918bd829d509441c2504135e'] mrr = [] for mdate in periods: my_df = test_df[(test_df['EndDate'].dt.to_period('M')>mdate ) & (test_df['first_order'].dt.to_period('M')<= mdate)] mmrr = my_df['Amount_per_month'].sum() mrr.append({'date':mdate,'mmrr':mmrr}) dates = [x['date'] for x in mrr] y = [x['mmrr'] for x in mrr] print(mrr) sns.set() plt.figure(figsize=(40,10)) plt.title('MRR by month') plt.ylabel('total') plt.bar(dates, y) plt.rc('font',**{'family' : 'normal', 'weight' : 'bold', 'size' : 60}) plt.show() MRR per client As we can see, all income from the client is evenly spread over the months. Conclusion We dismantled the calculation of MMR. Of course, this example is not the most combative. So in it, for example, there are no examples of changing the tariff for the client. ### Cohort Analysis in Python Cohort Analysis What is cohort analysis? Cohort analysis consists in studying the characteristics of cohorts / vintages / generations, united by common temporal characteristics.. A cohort/vintage/generation is a group formed in a specific way based on time: for example, the month of registration, the month of the first transaction, or the first visit to the site. Cohorts are very similar to segments, with the difference that a cohort includes groups of a certain period of time, while a segment can be based on any other characteristics. Why is it valuable? This kind of analysis can be helpful when it comes to understanding the health of your business and the stickiness of your customers. Stickiness is critical, as it is much cheaper and easier to retain a customer than it is to acquire new ones. Also, your product evolves over time. New features are added and removed, design changes, etc. Observing individual groups over time is the starting point for understanding how these changes affect user/group behavior. The problem For this task, we use the public dataset https://www.kaggle.com/olistbr/brazilian-ecommerce and the olist_orders_dataset.csv and olist_order_payments_dataset.csv files. You can connect them by order_id. Answer two questions: How many orders on average and how much do all cohorts make in the first year Compare any two cohorts by profit and orders Implementing Cohort Analysis in Python import pandas as pd import numpy as np import warnings warnings.filterwarnings("ignore") import seaborn as sns import matplotlib import matplotlib.pyplot as plt import matplotlib.ticker import matplotlib as mpl pd.set_option('max_columns', 50) mpl.rcParams['lines.linewidth'] = 2 %matplotlib inline sns.set_context( "notebook", font_scale = 1.5, rc = { "figure.figsize" : (30, 30), "axes.titlesize" : 18 } ) df_orders = pd.read_csv('data/olist_orders_dataset.csv') df_payments = pd.read_csv('data/olist_order_payments_dataset.csv') We import all the necessary libraries and read the files. We will build cohorts on the date of purchase (order_purchase_timestamp), so we will convert it to datetime64. Let's create an order_id and connect our datasets by it. df_orders['order_purchase_timestamp'] = pd.to_datetime(df_orders['order_purchase_timestamp']) df_payments = df_payments.set_index('order_id') df_orders = df_orders.set_index('order_id') order_payment = df_orders.join(df_payments) Since we are doing monthly cohorts, we will be looking at the overall monthly behavior of our clients. So we don't need granular order_purchase_timestamp. order_payment.reset_index(inplace=True) order_payment['Period'] = order_payment.order_purchase_timestamp.dt.strftime('%Y-%m') Let's create a new column, CohortGroup, which is the year and month when the order was first delivered to the customer. order_payment.set_index('customer_id', inplace=True) order_payment['CohortGroup'] = order_payment.groupby(level=0)['order_purchase_timestamp'].min().dt.strftime('%Y-%m')#.dt.apply(lambda x: x.strftime('%Y-%m')) order_payment.reset_index(inplace=True) Considering monthly cohorts, we need to aggregate customers, purchases and purchase amounts for each CohortGroup within a month (Period). grouped = order_payment.groupby(['CohortGroup', 'Period']) cohorts = grouped.agg({'customer_id': pd.Series.nunique, 'payment_value': 'sum', 'order_id': 'count'}) cohorts.rename(columns={'customer_id': 'TotalClients', 'order_id': 'TotalOrders'}, inplace=True) We want to see how each cohort behaved in the months following their first purchase, so we will need to index each cohort before their first month. For example, CohortPeriod = 1 would be the first month of the cohort, CohortPeriod = 2 would be their second, and so on. This allows us to compare cohorts at different stages of their lives. def cohort_period(df): df['CohortPeriod'] = np.arange(len(df)) + 1 return df cohorts = cohorts.groupby(level=0).apply(cohort_period) print(cohorts.head(10)) print(cohorts.tail(12)) Когорты Unfortunately, this dataset contains only the first month of the cohort. Based on these results, we can already compare cohorts. For example, the 2018-06 and 2018-07 cohort: The total number of customers and purchases has increased. But, let's count the purchases per customer: 2018-06 - 6419/6167 = 1.04 2018-07 - 6507/6292 = 1.03 Conclusion: on average, customers began to buy less often. For homework, write code that counts purchases per customer. Now let's calculate the average number of orders, customers and the average amount for each year. cohorts = cohorts.reset_index() cohorts['CohortGroupYear'] = cohorts['CohortGroup'].apply(lambda x: x.split('-')[0]) tt = cohorts.groupby('CohortGroupYear').agg({'payment_value': 'mean','TotalOrders':'mean','TotalClients':'mean'}) tt['ratio'] = tt['TotalOrders'] / tt['TotalClients'] print(tt) Когорты по годам For 2016, unfortunately, we have only 3 months with very strange values, and for 2018, only 10 months. We are already seeing growth in 2018 compared to 2017, but purchases per customer are declining. Conclusion Analyzed cohort analysis. It allows us to compare different groups of customers united by some criteria over time and understand how different versions of the product affect it. ### RFM analysis in Python The problem Make an RFM analysis. It divides users into segments depending on the prescription (Recency), frequency (Frequency) and the total amount of payments (Monetary). Recency - the difference between the current date and the date of the last payment Frequency — number of transactions Monetary - amount of purchases These three indicators must be calculated separately for each customer. Then put marks from 1-3 or 1-5. The wider the range, the narrower segments we get. Points can be set using quantiles. We sort the data according to one of the criteria and divide it into equal groups. For this task, we use the public dataset: https://www.kaggle.com/olistbr/brazilian-ecommerce nd the olist_orders_dataset.csv and olist_order_payments_dataset.csv files. You can connect them order_id. Implementing RFM in Python import numpy as np import pandas as pd %matplotlib inline import matplotlib import matplotlib.pyplot as plt from datetime import date,timedelta df_orders = pd.read_csv('data/olist_orders_dataset.csv') df_payments = pd.read_csv('data/olist_order_payments_dataset.csv') We import all the necessary libraries and read the files. We will rely on the date of delivery of the order by the carrier (order_delivered_carrier_date), so we will convert it to datetime64. Let's create an order_id index and connect our datasets by it. df_orders['order_delivered_carrier_date'] = pd.to_datetime(df_orders['order_delivered_carrier_date']) df_payments = df_payments.set_index('order_id') df_orders = df_orders.set_index('order_id') order_payment = df_orders.join(df_payments) Since the dataset is not the most recent, we will use max+1 instead of the current date. To create recency, frequency, and monetary, we'll group our records by customer_id. last_date = order_payment['order_delivered_carrier_date'].max() + timedelta(days=1) rfmTable = order_payment.reset_index().groupby('customer_id').agg({'order_delivered_carrier_date': lambda x: (last_date - x.max()).days, 'order_id': lambda x: len(x), 'payment_value': lambda x: x.sum()}) rfmTable.rename(columns={'order_delivered_carrier_date': 'recency', 'order_id': 'frequency', 'payment_value': 'monetary_value'}, inplace=True) RFM анализ Now we need to set the grades. We will split into a range from 1 to 5. The wider the range, the more accurate our groups, but at the same time, it is more difficult to work with a large number of combinations. quantiles = rfmTable.quantile(q=[0.20, 0.40, 0.60, 0.80]) quantiles = quantiles.to_dict() segmented_rfm = rfmTable def RScore(x,p,d): if x <= d[p][0.20]: return 1 elif x <= d[p][0.40]: return 2 elif x <= d[p][0.60]: return 3 elif x<=d[p][0.80]: return 4 else: return 5 segmented_rfm['r_quartile'] = segmented_rfm['recency'].apply(RScore, args=('recency',quantiles,)) segmented_rfm['f_quartile'] = segmented_rfm['frequency'].apply(RScore, args=('frequency',quantiles,)) segmented_rfm['m_quartile'] = segmented_rfm['monetary_value'].apply(RScore, args=('monetary_value',quantiles,)) segmented_rfm['RFMScore'] = segmented_rfm.r_quartile.map(str) + segmented_rfm.f_quartile.map(str) + segmented_rfm.m_quartile.map(str) print(segmented_rfm.head()) RFM Score Separately, we can see the average value of recency for all RFMScore. fig=plt.figure(figsize=(18, 16), dpi= 80, facecolor='w', edgecolor='k') segmented_rfm.groupby('RFMScore').agg('recency').mean().plot(kind='bar', colormap='Blues_r') plt.show() Recency Score While it may not be very informative. Let's try to understand how to use the analysis results. How to use the results of RFM analysis The purpose of RFM analysis is to form segments and, depending on the segment, influence them in a certain way. For example: offer a bonus, benefit, send a push or email notification. It's important to do it in a targeted way. The effect of using RFM analysis can be as follows: customer retention, increased income, increased customer loyalty. Examples of interpretation of RFM analysis segments: R=5, F=5, M=5 — they pay often, a lot and recently. The most loyal and active users. R=1, F=1, M=1 - they pay little, rarely and for a long time. Most likely lost customers. It may not be worth taking action to return them if the cost of attraction is higher than the expected profit. R=1/2, F=4/5, M=4/5 — loyal users on the verge of leaving. We offer them a bonus, a discount and try to return them. R=4/5, F=1, M=1/2/3/4/5 — Users have recently made a payment. We try to encourage them to buy more. Conclusion We dismantled a simple and effective way to segment users / customers. RFM analysis will help you choose targeted exposure and thus increase revenue or retain users. ### Способы регистрации обращений клиентов Наиболее предпочтительным для пользователей и наиболее быстрым способом регистрации обращений является телефонная связь, рассмотрим 2 метода организации приема и маршрутизации обращений, поступающих посредством телефонных звонков. Суть первого метода заключается в регистрации и разрешении 70% обращений без маршрутизации (эскалации) на вторую линию, при обеспечении максимальной доступности операторов и полноты информации, необходимой для обработки обращений на второй линии. Для реализации данного метода необходимо наличие на первой линии высококвалифицированных специалистов, способных разрешать поступающие обращения с высокой скоростью. Для определения необходимого количества операторов первой линии применялись расчеты методом Эрланга (данный метод позволяет определить количество операторов с учетом пиковых нагрузок). Расчет данных методом используются следующие входные параметры: среднее время разговора, среднее время пост-обработки звонка (время, необходимое оператору на решение обращения и занесение информации в базу), число звонков в час, средняя задержка при ответе на звонок. Для примера возьмем данные с Benchmark Portal (таблице 1). Таблица 1. Количество операторовВероятность соединения с оператором без постановки в очередьСреднее время ожидания, секСредняя длина очередиУровень обслуживания*Занятость операторов212 %3156444 %98 %2213 %8871218 %93 %2327 %436634 %89 %2443 %242351 %86 %2558 %140265 %82 %2670 %82176 %79 %2779 %48184 %76 %2886 %28090 %73 %2991 %16093 %71 %Для расчетов использовались следующие параметры:Среднее время разговора — 8 мин; Среднее время пост-обработки звонка — 16 мин; Число звонков в час — 50; Средняя задержка при ответе на звонок — 1 мин.* Количество звонков, ожидавших меньше заданного интервала (60 сек) Как видно из результатов расчета для оптимальной регистрации и обработки обращений на первой линии необходимо минимум 24-25 операторов и 7-10 телефонных линий. Данная модель не выгодна, так как требует наличия большого количества высококвалифицированных специалистов на первой линии, а их отсутствие резко снижает качество обслуживания. В связи с чем, предлагаю рассмотреть второй метод организации приема и маршрутизации обращений, основанный на регистрации и маршрутизации обращений пользователей на вторую линию, при обеспечении максимальной доступности операторов и полноты информации, необходимой для обработки обращения на второй линии. Во втором методе предполагается сокращение времени пост-обработки (Время пост-обработки звонка — время, необходимое оператору на решение обращения и  занесение информации в базу) звонка с 16 до 4 минут, за счет оперативной передачи обращения на вторую линию. Тем самым повышая доступность операторов первой линии. Расчеты приведены в таблице 2. Таблица 2. Количество операторовВероятность соединения с оператором без постановки в очередьСреднее время ожидания, секСредняя длина очередиУровень обслуживания*Занятость операторов1117 %600823 %91 %1239 %220348 %83 %1359 %98168 %77 %1474 %46182 %71 %1585 %22090 %67 %1691 %10095 %63 %Для расчетов использовались следующие параметры:Среднее время разговора — 8 мин; Среднее время пост-обработки звонка — 4 мин; Число звонков в час — 50; Средняя задержка при ответе на звонок — 1 мин.* Количество звонков, ожидавших меньше заданного интервала (60 сек) Данная модель более применима, так как исключает возможность перегрузки первой линии и позволяет нанимать на первую линию менее квалифицированных и менее дорогостоящих специалистов. Перечень обращений, решаемых первой линией, может изменяться по мере повышения компетентности ее специалистов. С целью повышения эффективности на этапе регистрации обращений, поступающих по телефону, возможно применения следующего показателя (KPI) характеризующие доступность операторов:А= (Число обслуженных вызовов в течении Х секунд (уложились в заданное среднее время обработки каждого звонка) )/(общее число обслуженных вызовов (за день)+общее число потерянных вызовов (за день))*100 Для оценки полноты регистрации обращений, поступающих на первую линию по телефону, можно использовать следующий показатель:B=(Количество зарегистрированных обращений (по данным из системы учета обращений))/(Общее количество обслуженных обращений более N секунд (по данным из системы AVAYA)) Данные показатели можно устанавливать как на группу, так и на отдельных операторов. Применение вышеуказанных показателей возможно после внедрения системы AVAYA. Определение приоритета для обращений Первый метод расчета приоритета позволяет проставлять срок исполнения обращения (возможно сделать это в формате жестких рамок SLA\OLA или скоринговой системы) в зависимости от системы, по которой происходит обращение и срочности обращения. Каждой системе (сервису) назначается рейтинг критичности от 0 до 10, а каждому обращению по системе одна из трёх категорий срочности (Высокая, Средняя, Низкая) и их числовой эквивалент (1, 2, 3 соответственно). Время на выполнение конкретного обращения (Т) вычисляется по формуле:T =K1*(Срочность обращения(числовой эквивалент))/(Рейтинг критичности)*60минутK1 — поправочный коэффициент, определяемый эмпирически (рекомендуемое значение от 4-6) В результате данных вычислений должна получиться следующая матрица: Процесс AПроцесс BПроцесс СКритичность1097Срочностьвысокая30 мин33,3 мин42 минсредняя60 мин66,7 мин86 миннизкая100 мин111 мин143 мин По ней система назначает конкретному обращению время на обработку. Обращения сортируются, по времени оставшемуся на их обработку. Второй метод расчета приоритета основан на соблюдении сроков SLA.С целью соблюдения сроков решения обращений предлагаем метод динамического изменения приоритета в зависимости от времени, установленного в соглашении об уровне обслуживания (далее SLA). Для реализации данного метода необходимо: Определить перечень всех типов обращений; Для каждого типа обращения определить минимальное время его выполнения; Для каждого типа обращения определить максимальное время для обработки обращения, равное троекратному минимальному времени; Определить временные интервалы категорий SLA (категориям, которых не должно быть более 4-х); Типы обращений группируется по категориям SLA, на основе максимального времени, попавшего в заданный временной интервал; По каждой категории необходимо согласовать SLA с бизнес подразделениями. Пример в таблице 3. Таблица 3. Тип обращенияМинимальное время обработки обращенияМаксимальное времяКатегория SLAУстановка принтера2060АНастройка сервера60180ВНастройка коммуникационного оборудования1545АУстановка телефона3090ВКатегории SLA: А — менее часа; В — от часа до 3 часов; С — более 3 часов. Необходимо разделить обработку обращений по 3 приоритетам: низкий, средний и высокий. Каждое вновь поступившее обращение попадает в зону низкого приоритета. По истечению 1/3 времени от установленного в категории SLA заявка попадает в  зону среднего приоритета, по истечению 2/3 времени — в зону высокого приоритета. Обработка обращений должна начинаться с более приоритетных зон (сначала высокий, затем средний и в последнюю очередь — низкий), в случае отсутствия заданий в зоне с высоким приоритетом обрабатываются задания из зоны с более низким приоритетом. В случае превышения срока, установленного в SLA, обращение попадает в зону просрочен. Пример в таблице 4. Таблица 4. время в часах1 час2 час3 час4 часчисло новых обращений4100Установка принтераВысокий на решение обращения ушло 30 минНастройка сервераНизкийСреднийВысокий на решение обращения ушло 60 минНастройка коммуникационного оборудованияВысокий на решение обращения ушло 30 минВысокий на решение обращения ушло 15 минУстановка телефонаСреднийВысокий на решение обращения ушло 45 мин Использование данного метода позволит: определить оптимальное количество операторов на второй линии (в разрезе профильных секторов). Что достигается с помощью отслеживания доли обращений, находящихся в зонах высокого и низкого приоритета, что может свидетельствовать о недостатке или избыточности ресурсов. сократить количество обращений, время решения которых превысило установленное в SLA. Что достигается посредством контроля над очередью и сокращения количества обращений в зоне высокого приоритета. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Как подготовиться к Data Science интервью Data Science интервью - непростая задача. Существует значительная неопределённость в отношении вопросов. Независимо от того, какой у вас опыт работы или какой у вас диплом об образовании, интервьюер может задать вам ряд вопросов, которые вы не ожидаете. Во время Data Science интервью интервьюер будет задавать технические вопросы по широкому кругу тем, требуя от интервьюируемого как сильных знаний, так и хороших коммуникативных навыков. В этой заметке я хотел бы поговорить о том, как подготовиться к собеседованию по машинному обучению. Разберем категории вопросов, поделюсь ссылками с вопросами и ответами на часто задаваемые вопросы. Категории вопросов Традиционно Data Science интервью включает следующие категории вопросов: Статистика Алгоритмы машинного обучения Навыки программирования, алгоритмы и структуры данных Знание предметной области Проектирование систем машинного обучения Поведенческое интервью Соответствие культуре Решение проблем Статистика Без глубоких знаний статистики трудно добиться успеха в качестве специалиста по анализу данных - соответственно, интервьюер попытается проверить ваше понимание предмета с помощью вопросов ориентированных на статистику. Будьте готовы ответить на некоторые фундаментальные статистические вопросы в ходе интервью. Проектирование систем машинного обучения В этом блоке вопросов есть несколько основных подтем: Сетап проекта Конвейер данных Моделирование: выбор данных, обучение и отладка. Продакшен: тестирование, развертывание и поддержка Руководство по подготовке Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. Поведенческое интервью Работодатели любят поведенческие интервью. Они раскрывают информацию об опыте, поведении респондента и о том, как это может повлиять на остальную команду. С помощью этих вопросов интервьюер хочет увидеть, как кандидат реагировал на ситуации в прошлом, насколько хорошо он может сформулировать свою роль и чему он научился на своем опыте.Вам могут задать вопросы из нескольких поведенческих категорий: Работа в команде Лидерство Управление конфликтами Решение проблем Неудачи Перед собеседованием запишите примеры из опыта работы, связанные с этими темами, чтобы освежить свою память - вам нужно будет запомнить конкретные примеры, чтобы хорошо отвечать на вопросы. Соответствие культуре Работодатель часто пытается выяснить, откуда у вас интерес к науке о данных и компании по найму. Нет причин не быть собой. На эти вопросы нет правильных ответов, но лучшие ответы даются с уверенностью. Решение проблем В какой-то момент во время собеседования интервьюеры захотят проверить вашу способность решать проблемы. Часто эти тесты остаются открытым вопросом: как бы вы справились с X? В общем, этот X будет обозначать задачу или проблему, характерную для компании, в которую вы подаете заявку. Несколько простых советов: не бойтесь задавать вопросы. Работодатели хотят проверить ваши навыки критического мышления, и задавать вопросы, проясняющие моменты неопределенности, - это черта, которой должен обладать любой специалист по данным. Кроме того, если проблема дает возможность продемонстрировать свои навыки программирования на доске или создать схематические диаграммы, используйте это в своих интересах. Вывод Не существует единого «лучшего» способа подготовиться к собеседованию, но, надеюсь, изучив эти общие вопросы для специалистов по данным, вы сможете пройти собеседование. Удачи! Полезные ссылки https://github.com/khangich/machine-learning-interview https://github.com/rbhatia46/Data-Science-Interview-Resources https://www.springboard.com/blog/ai-machine-learning/machine-learning-interview-questions/ https://github.com/iamtodor/data-science-interview-questions-and-answers https://medium.com/analytics-vidhya/test-your-skills-26-data-science-interview-questions-answers-69cb2b223e57 Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Medical Image Analysis In Python Medical Image Analysis In Python The field of medical imaging has become very popular in recent years. Therefore, I write book where you will learn the basics of medical image analysis using Python. You will study CT and X-ray scans, segment images, and analyze metadata. Even if you have not used with medical imaging before, you will have all the necessary skills upon completion of the book. Prerequisites It assumes you already know how to program in Python. This book is not intended for beginners in Python. Required libraries: matplotlib, numpy, pandas. Knowledge of opencv and skimage would be a plus. It is also advisable to have experience with the Linux command line. I wrote the Medical Image Analysis In Python booklet. What awaits you in this book? You will be introduced to medical imaging research. Understand the DICOM and NIfTI-1 Data Format. Learn to analyze meta tags, convert and anonymize data. Learn what Windowing and Hounsfield units are and how to apply them. Understand the task of image segmentation. Take a look at third party libraries for medical image segmentation. Get to know fastai.medical.imaging. The course is accompanied by several test tasks and a chat in the telegram for discussion. What exactly will not be in this book? This course will not include Deep Learning. We will be focusing specifically on the medical imaging format. I wrote the Medical Image Analysis In Python booklet. Read more my post: How to prepare for a data science interview ### Simple steps to make your Python code better Many of you have GIT code repositories, in this post I'll show you how to make your Python code better. I'll use this repository as an example: https://github.com/Aykhan-sh/pandaseda Fork it and try to make the code better. Improving code readability Improving the readability of your code is easy. We will use libraries for syntax formatting and validation. First, let's create configuration files for flake8, mypy and black in the repository. Let's install them first: pip install black flake8 mypy Take a look at flake8. Flake8 is a tool that allows you to scan a project's code and detect stylistic errors and violations of various Python code conventions. File setup.cfg  for flake8 and mypy [flake8] max-line-length = 120 exclude =.git,__pycache__,docs/source/conf.py,build,dist,tests ignore = I101,D100,D101,D102,D103,D104,D105,D107,D401,E203,I900,N802,N806,N812,W503,S311,S605,S607,ISC003,ISC001,T101,T000,F541,PL123 per-file-ignores = __init__.py:F401,F403 [mypy] ignore_missing_imports = True disallow_untyped_defs = True check_untyped_defs = True warn_redundant_casts = True no_implicit_optional = True strict_optional = True [mypy-tests.*] ignore_errors = True Parse the [flake8] block: max-line-length - maximum line length exclude - list of folders excluded from flake8 scanning ignore - a list of errors / warnings that are also excluded. For example: I101: The names in your from import are in the wrong order and D100 - Missing docstring per-file-ignores - exclude a specific file from scanning flake8 is very easy to run: flake8 Remember that flake8 does not modify the code, it will simply test it. Errors will have to be corrected manually. Now let's talk about mypy. Python does not have mandatory static typing, but it is recommended to add types to function arguments and return types. To do this, just run mypy and don't forget to correct the errors: mypy. Create a pyproject.toml file for black. black will help you format your code according to the standard. File pyproject.toml [tool.black] line-length = 119 target-version = ['py36'] include = '\.pyi?$' exclude = ''' /( \.eggs | \.git | \.hg | \.mypy_cache | \.tox | \.venv | _build | buck-out | build | dist )/ ''' Analyze the code: line-length - line length target-version - Python versions. py36 - Python 3.6, it is possible for other versions as well. include - a list of what to include in the formatting exclude - a list of what to exclude from formatting The launch is also very simple: black. I recommend saving the edited file. I have also fixed all mypy errors. Let's take a look at what has changed. This is what the code looked like before it was edited: Python code before black And so after editing: Python code after black The code has become more readable and now we have static typing. Pay particular attention to the Union type. It is necessary to use it when it is allowed to use not all types, but only some. You need to list them in square brackets. isort isort is a Python library for sorting imports alphabetically, with automatic division into sections and by type. Installation: pip install isort Usage: isort. This is how our imports looked before editing: imports before isort And so after applying isort: imports after isort I also recommend saving the edited file. pre-commit hook We can run black, flake8 and mypy manually, but this is not convenient. We can automate the process using a pre-commit hook. File .pre-commit-config.yaml repos: - repo: https://github.com/asottile/pyupgrade rev: v2.19.4 hooks: - id: pyupgrade args: [ "--py38-plus" ] - repo: https://github.com/pre-commit/mirrors-isort rev: 1ba6bfc # Use the revision sha / tag you want to point at hooks: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black rev: 21.6b0 hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 rev: 3.9.2 hooks: - id: flake8 language_version: python3 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.0.1 hooks: - id: check-docstring-first - id: check-json - id: check-merge-conflict - id: check-yaml - id: debug-statements - id: end-of-file-fixer - id: trailing-whitespace - id: requirements-txt-fixer - repo: https://github.com/pre-commit/mirrors-pylint rev: 56b3cb4 hooks: - id: pylint args: - --max-line-length=120 - --ignore-imports=yes - -d duplicate-code - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.9.0 hooks: - id: python-check-mock-methods - id: python-use-type-annotations - id: python-check-blanket-noqa - id: python-use-type-annotations - id: text-unicode-replacement-char - repo: https://github.com/pre-commit/mirrors-mypy rev: 9feadeb hooks: - id: mypy exclude: ^tests/ args: [ --disallow-untyped-defs, --check-untyped-defs, --warn-redundant-casts, --no-implicit-optional, --strict-optional ] Now each commit will trigger our formatting and validation. Now let's make Github run them on every pull request. Github Actions For our purposes, we will use Github Action. Let's create a ci.yaml file File .github/workflows/ci.yaml name: Python package on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: [3.6] steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} # You can test your matrix by printing the current Python version - name: Display Python version run: python -c "import sys; print(sys.version)" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements_dev.txt - name: Run black run: black --check . - name: Run flake8 run: flake8 - name: Run Mypy run: mypy pandaseda Pay particular attention to: - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements_dev.txt - name: Run black run: black --check . - name: Run flake8 run: flake8 - name: Run Mypy run: mypy pandaseda Here are our checks. Run Black here with the check flag. Black will not edit the code, but it will check. That is why it is better to save the file after running black beforehand. Action is now ready, you can run it on any commit. After launch, you can see the progress and the result in the Action tab. Github Action In case of errors, an email will be sent to the mail: Github Action email The error itself can also be viewed in Action: Github Action Log Conclusion In this post, I managed to consider several libraries for working with your code. We looked at the pre-commit hook and Github Actions separately. Additional material GitHub Actions Documentation isort mypy documentation black Read more my posts ### Простые шаги сделать ваш Python код лучше У многих из вас есть GIT- репозитории с кодом, в этой заметке я расскажу как сделать ваш Python код лучше. В качестве примера я буду использовать этот репозиторий: https://github.com/Aykhan-sh/pandaseda Форкнем его и попробуем сделать код лучше. Улучшим читаемость кода Улучшить читаемость вашего кода очень просто. Мы будем использовать библиотеки для синтаксического форматирования и проверки. Для начала создадим в репозитории файлы конфигураций для flake8, mypy и black Установим их для начала: pip install black flake8 mypy Разберем flake8. Flake8 — инструмент, позволяющий просканировать код проекта и обнаружить в нем стилистические ошибки и нарушения различных конвенций кода на Python. Файл setup.cfg для flake8 и mypy [flake8] max-line-length = 120 exclude =.git,__pycache__,docs/source/conf.py,build,dist,tests ignore = I101,D100,D101,D102,D103,D104,D105,D107,D401,E203,I900,N802,N806,N812,W503,S311,S605,S607,ISC003,ISC001,T101,T000,F541,PL123 per-file-ignores = __init__.py:F401,F403 [mypy] ignore_missing_imports = True disallow_untyped_defs = True check_untyped_defs = True warn_redundant_casts = True no_implicit_optional = True strict_optional = True [mypy-tests.*] ignore_errors = True Блок [flake8]: max-line-length - максимальная длина строки exclude - список папок, которые исключаются из сканирования flake8 ignore - список ошибок/ предупреждений, которые так же исключаются. Например: I101: The names in your from import are in the wrong order и D100 — Missing docstring per-file-ignores - исключить из сканирования определенный файл flake8 запустить очень просто: flake8 Помните, что flake8 не модифицирует код, а просто проверят его. Подправить ошибки придется в ручную. Теперь поговорим про mypy. У Python нет обязательной статической типизации, но рекомендуется добавлять типы в аргументы функции и возвращаемые типы. Для этого просто запустим mypy и не забудьте подправить ошибки: mypy . Создадим файл pyproject.toml для black. black поможет форматировать ваш код в соответствии со стандартом. Файл pyproject.toml [tool.black] line-length = 119 target-version = ['py36'] include = '\.pyi?$' exclude = ''' /( \.eggs | \.git | \.hg | \.mypy_cache | \.tox | \.venv | _build | buck-out | build | dist )/ ''' Разберём код: line-length - длина строки target-version - версии Python. py36 - Python 3.6, можно и для других версий. include - список того, что включаем в форматирование exclude - список того, что исключаем из форматирования Запуск тоже очень простой: black . Рекомендую сохранить отредактированный файл. Так же я уже исправил все ошибки mypy. Взглянем, что же поменялось. Так выглядел код до правки: Код до применения black А так после правки: Код после применения black Код стал читабельнее и теперь у нас статическая типизация. Особое внимание обратите на тип Union. Использовать его необходимо когда допускается использование не любых типов, а только некоторых. Перечислить их нужно в квадратных скобках. isort isort - это библиотека Python для сортировки импорта по алфавиту с автоматическим разделением на разделы и по типу. Установка: pip install isort Использование: isort . Так выглядели наши импорты до правки: Импорты до isort А так после применения isort: Импорты после isort Так же рекомендую сохранить отредактированный файл. pre-commit hook Мы можем запускать black, flake8 и mypy вручную, но это не удобно. Мы можем автоматизировать процесс с помощью pre-commit hook. Файл .pre-commit-config.yaml repos: - repo: https://github.com/asottile/pyupgrade rev: v2.19.4 hooks: - id: pyupgrade args: [ "--py38-plus" ] - repo: https://github.com/pre-commit/mirrors-isort rev: 1ba6bfc # Use the revision sha / tag you want to point at hooks: - id: isort args: ["--profile", "black"] - repo: https://github.com/psf/black rev: 21.6b0 hooks: - id: black - repo: https://gitlab.com/pycqa/flake8 rev: 3.9.2 hooks: - id: flake8 language_version: python3 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.0.1 hooks: - id: check-docstring-first - id: check-json - id: check-merge-conflict - id: check-yaml - id: debug-statements - id: end-of-file-fixer - id: trailing-whitespace - id: requirements-txt-fixer - repo: https://github.com/pre-commit/mirrors-pylint rev: 56b3cb4 hooks: - id: pylint args: - --max-line-length=120 - --ignore-imports=yes - -d duplicate-code - repo: https://github.com/pre-commit/pygrep-hooks rev: v1.9.0 hooks: - id: python-check-mock-methods - id: python-use-type-annotations - id: python-check-blanket-noqa - id: python-use-type-annotations - id: text-unicode-replacement-char - repo: https://github.com/pre-commit/mirrors-mypy rev: 9feadeb hooks: - id: mypy exclude: ^tests/ args: [ --disallow-untyped-defs, --check-untyped-defs, --warn-redundant-casts, --no-implicit-optional, --strict-optional ] Теперь каждый коммит будет запускаться наше форматирование и проверки. Теперь сделаем, что бы Github запускал их при каждом pull request. Github Actions Для наших целей будем использовать Github Action. Создадим файл ci.yaml Файл .github/workflows/ci.yaml name: Python package on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: [3.6] steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} # You can test your matrix by printing the current Python version - name: Display Python version run: python -c "import sys; print(sys.version)" - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements_dev.txt - name: Run black run: black --check . - name: Run flake8 run: flake8 - name: Run Mypy run: mypy pandaseda Основное внимание обратите на: - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements_dev.txt - name: Run black run: black --check . - name: Run flake8 run: flake8 - name: Run Mypy run: mypy pandaseda Тут указаны наши проверки. Black тут запускаем с флагом check. Black не будет редактировать код, но выполнит проверку. Именно поэтому лучше сохранить файл после запуска black заранее. Action теперь готов, его можно запустить при любом коммите. После запуска можно посмотреть ход выполнения и результат во вкладке Action. Github Action В случае ошибок на почту будет отправлен email: Github Action email Саму ошибку можно так же посмотреть в Action: Github Action Log Заключение В этой заметке получилось рассмотреть несколько библиотек для работы с вашим кодом. Отдельно рассмотрели pre-commit hook и Github Actions. Дополнительный материал Документация по GitHub Actions isort Документация по mypy Стильный код на Python, или учимся использовать Flake8 black Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### How to prepare for a data science interview Data science interview is not easy. There is considerable uncertainty about the issues. Regardless of what kind of work experience you have or what kind of data science certification you have, the interviewer may be throwing you a series of questions that you weren't expecting. During a data science interview, the interviewer will have technical questions on a wide range of topics, requiring the interviewee to have both strong knowledge and good communication skills. In this note, I would like to talk about how to prepare for a machine learning science / interview date. We will sort out the categories of questions, I will share links with questions and answers to frequently asked questions. Question categories Traditionally, data science / machine learning interviews include the following categories of questions: Statistics Machine learning algorithms Programming skills, algorithms and data structures Knowledge of the domain area Machine Learning Systems Design Behavioral Culture Fit Problem-Solving Statistics Without a deep knowledge of statistics, it is difficult to succeed as a data scientist - accordingly, a interviewer will try to test your understanding of the subject with statistics-oriented data science interview questions. Be prepared to answer some fundamental statistical questions as part of your interview. Machine Learning Systems Design There are several main headings in this block of questions: Setting up the project Data pipeline Modeling: selection, training and debugging. Service: testing, deployment and supportPreparation guide Behavioral Employers love questions about behavior. They reveal information about the respondent's experience, behavior, and how this might affect the rest of the team. With these questions, the interviewer wants to see how the candidate has responded to situations in the past, how well they can articulate their role, and what they have learned from their experience.You may be asked several categories of behavioral questions: Teamwork Leadership Conflict management Problem solving FailuresBefore the interview, write down examples of work experience related to these topics to refresh your memory - you will need to remember specific examples in order to answer the questions well. Culture fit An employer often tries to figure out where your interest in data science and a hiring company comes from. There is no reason not to be yourself. There are no right answers to these questions, but the best answers are given with confidence. Problem-Solving At some point during the interview, interviewers will want to test your problem-solving ability with data science interview questions. Often these tests are an open question: How would you handle X? In general, this X will represent a task or problem specific to the company you are applying to. A few quick tips: Don't be afraid to ask questions. Employers want to test your critical thinking skills, and asking questions that clarify points of uncertainty is a trait any data scientist should have. Also, if the problem provides an opportunity to demonstrate your programming skills on a whiteboard or create schematic diagrams, use that to your advantage. Conclusion There is no single “best” way to prepare for a data science interview, but hopefully, by learning these common questions for data scientists, you will be able to pass your interview with good practice and confidence. If you have any suggestions for questions, let us know! Good luck. Useful links https://github.com/khangich/machine-learning-interview https://github.com/rbhatia46/Data-Science-Interview-Resources https://www.springboard.com/blog/ai-machine-learning/machine-learning-interview-questions/ https://github.com/iamtodor/data-science-interview-questions-and-answers https://medium.com/analytics-vidhya/test-your-skills-26-data-science-interview-questions-answers-69cb2b223e57 Read more my posts ### BentoML - Faster Machine Learning Prototype In this post, I'll show you how to create a working prototype of a web application with a working machine learning model in 50 lines of Python code. Imagine you have a cool project idea. Now you need to implement MVP (minimum viable product) and show it to your manager / partner / investor or just show off to your friends. We will be using BentoML. It is a flexible, high-performance platform that is ideal for building an MVP. BentoML features: supports multiple machine learning frameworks including Tensorflow, PyTorch, Keras, XGBoost, and more. own cloud deployment with Docker, Kubernetes, AWS, Azure and many more high performance online service via API web dashboards and APIs for managing model registry and deployment Create MVP First, download the html page with css and pictures from the repository. Now let's write runner.py. We will be doing a demo for the classic iris classification problem. Let's start by importing the libraries: from sklearn import svm from sklearn import datasets from bentoml import env, artifacts, api, BentoService from bentoml.adapters import DataframeInput from bentoml.frameworks.sklearn import SklearnModelArtifact from bentoml.adapters import DataframeInput from bentoml.artifact import SklearnModelArtifact Let's import all the necessary bento elements: environment, artifacts, API, service for the base model, and static content. from bentoml import (env, # environment artifacts, # artifacts api, # API BentoService, # service for the base model web_static_content # static content Let's write our classifier class. We will receive data in batches and make a predictive: class Classifier(BentoService): @api(input=DataframeInput(), batch=True) def test(self, df): return self.artifacts.model.predict(df) And finally, let's write the launch of our MVP itself: if __name__ == "__main__": # Загрузим датасет и обучим простую модель iris = datasets.load_iris() X, y = iris.data, iris.target clf = svm.SVC(gamma='scale') clf.fit(X, y) # Инициализируем класс классификатора iris_classifier_service = Classifier() # Закинем модель в артифакт iris_classifier_service.pack('model', clf) # Сохраним и запустим saved_path = iris_classifier_service.save() Then the fun begins. Let's run our runner.py: python runner.py A docker-like container will be created, which will then need to be called the latest version of the container: bentoML start bentoml serve Classifier:latest Now our MVP will be available at http://127.0.0.1:5000, where predictions will be made by choosing the parameters of the irises. bentoML serve Docker A ready-to-deploy docker container image can now be created with just one command: bentoml containerize Classifier:latest -t my_prediction_service:v1 docker run -p 5000:5000 my_prediction_service:v3 --workers 2 Conclusion In this post, we looked at a very simple tool that is great for building and demonstrating an MVP. Additional material bentoML repository official documentation Link to the repository with the code from the note Read more my posts ### BentoML - быстрый Machine Learning прототип В заметке я расскажу как в 50 строчек Python кода создать рабочий прототип веб приложения с рабочей моделью машинного обучения. Представьте, что у вас есть классная идея проекта. Теперь нужно реализовать MVP (minimum viable product) и показать его менеджеру/партнеру/ инвестору или просто похвастаться перед друзьями. Мы будем использовать BentoML. Это гибкая высокопроизводительная платформа, которая идеально подходит для создания MVP. Возможности BentoML: поддерживает несколько фреймворков машинного обучения, включая Tensorflow, PyTorch, Keras, XGBoost и другие. собственное облачное развертывание с Docker, Kubernetes, AWS, Azure и многими другими высокопроизводительное онлайн-обслуживание через API веб-панели мониторинга и API для управления реестром моделей и развертыванием Создадим MVP Для начала скачайте свёрстанную страницу со стилями и картинками с репозитория. Теперь напишем runner.py. Мы будем делать демо для классической задачи классификации ирисов. Начнем с импорта библиотек: from sklearn import svm from sklearn import datasets from bentoml import env, artifacts, api, BentoService from bentoml.adapters import DataframeInput from bentoml.frameworks.sklearn import SklearnModelArtifact from bentoml.adapters import DataframeInput from bentoml.artifact import SklearnModelArtifact Импортнем все нужные bento элементы: среду выполнения, артифакты, API, сервис для базовой модели и статичный контент. from bentoml import (env, # среда artifacts, # артифакты api, # общение с API BentoService, # сервис для модели web_static_content # статичный контент Напишем наш класс классификатора. Будем получать данные батчами и делать предикт: class Classifier(BentoService): @api(input=DataframeInput(), batch=True) def test(self, df): return self.artifacts.model.predict(df) Ну и наконец напишем сам запуск нашего MVP: if __name__ == "__main__": # Загрузим датасет и обучим простую модель iris = datasets.load_iris() X, y = iris.data, iris.target clf = svm.SVC(gamma='scale') clf.fit(X, y) # Инициализируем класс классификатора iris_classifier_service = Classifier() # Закинем модель в артифакт iris_classifier_service.pack('model', clf) # Сохраним и запустим saved_path = iris_classifier_service.save() Дальше начинается самое интересное. Запустим наш runner.py: python runner.py Создастся свой контейнер на подобие докера, который потом и надо будет вызвать последнюю версию контейнера: bentoML start bentoml serve Classifier:latest Теперь по адресу http://127.0.0.1:5000 будет доступен наш MVP, где выбирая параметры ирисов будут делаться предсказания. bentoML serve Docker Готовый к развертыванию образ контейнера докера теперь можно создать с помощью всего одной команды: bentoml containerize Classifier:latest -t my_prediction_service:v1 docker run -p 5000:5000 my_prediction_service:v3 --workers 2 Заключение В этой заметке мы рассмотрели очень простой инструмент, который отлично подходит для создания и демонстрации MVP. Дополнительный материал репозиторий bentoML официальная документация Ссылка на репозиторий с кодом из заметки Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Курс - анализ медицинских изображений в Python Анализ медицинских изображений в Python Область медицинской визуализации стала очень популярной в последние годы, но для новичков даже загрузка данных может быть проблемой. Поэтому я сделал курс, где вы изучите основы анализа медицинских изображений с помощью Python. Вы будете изучать КТ и рентген снимки, сегментировать области изображения и проводить анализ метаданных. Даже если вы никогда раньше не работали с медицинскими изображениями, то по завершению курса вы будете обладать всеми необходимы навыками. Пререквизиты Предполагается, что вы уже умеете программировать на Python. Курс не рассчитан на начинающих в Python. Необходимые библиотеки: matplotlib, numpy, pandas. Знание opencv и skimage будет плюсом. Также желательно иметь опыт работы с командной строкой Linux. Что вас ждёт в этом курсе? Вы познакомитесь с исследованием медицинских изображений. Разберётесь с форматами DICOM и NIfTI-1 Data Format. Научитесь анализировать метатеги, конвертировать и анонимизировать данные. Узнаете, что такое Windowing и единицы Хаунсфилда и как их применять. Разберетесь с задачей сегментацией изображений. Посмотрите на сторонние библиотеки для сегментации медицинских изображений. Познакомитесь с fastai.medical.imaging. Курс сопровождён несколькими тестовыми заданиями и чатом в телеграме для обсуждений. Чего точно не будет в этом курсе? В этом курсе не будет Deep Learning. Мы будем сфокусированы именно на формате медицинских изображений. Ссылка на курс Больше постов Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Расчет Monthly Recurring Revenue (MRR) в Python Что такое Monthly Recurring Revenue? Monthly Recurring Revenue — регулярный месячный доход. Эта метрика применяется в основном в подписных моделях. При этом сам доход нужно привести к месяцам. Почему это ценно? Если у нас есть подписной сервис мы имеем регулярныее или периодические платежи, то мы можем понять сколько денег мы заработаем и насколько наш бизнес эффективен. Далее, мы можем увеличить MRR за счет перехода клиентов на более дорогой тариф или попробовать снизить отток клиентов. Постановка задачи Для этой задачи используйте новый датасет: https://alimbekov.com/wp-content/uploads/2021/03/mrr.csv Структура: customer_id - знакомый нам уже ID клиента first_order - Дата начала подписки EndDate - Дата окончания подписки rate - план подписки (месячный, полугодовой, годовой) Amount - оплаченная сумма commission - коммисия платежный систем Будем использовать следующую формулу для расчёта MRR: MRR = new + old + expansion + reactivation - churn - contraction new MRR - первый платеж нового клиента old MRR - повторяющийся платеж клиента expansion MRR - увелечение MRR в связи с новым тарифом contraction MRR - уменьшение MRR в связи с новым тарифом churn MRR - отток MRR в связи с прекращением платежа reactivation MRR - возврат клиента, у которого был отток MRR Реализация расчета Monthly Recurring Revenue (MRR) в Python import pandas as pd import numpy as np import warnings warnings.filterwarnings("ignore") import seaborn as sns import matplotlib import matplotlib.pyplot as plt import matplotlib.ticker import matplotlib as mpl pd.set_option('max_columns', 50) mpl.rcParams['lines.linewidth'] = 2 %matplotlib inline sns.set_context( "notebook", font_scale = 1.5, rc = { "figure.figsize" : (30, 30), "axes.titlesize" : 18 } ) df_mrr = pd.read_csv('mrr.csv') Импортируем все необходимые библиотеки и считаем файл. Давайте теперь сделаем несколько необходимых расчетов для дальнейшей работы. Приведем все даты к нужному формату, вычислим длительность подписки, извлечем месяц и год из даты подписки, посчитаем сумму за вычетом комиссии (комиссия везде 5%) и узнаем сумму, которую мы получаем в месяц. df_mrr['first_order'] = pd.to_datetime(df_mrr['first_order']) df_mrr['EndDate'] = pd.to_datetime(df_mrr['EndDate']) df_mrr['Period'] = (df_mrr.EndDate.dt.to_period('M').astype(int) - df_mrr.first_order.dt.to_period('M').astype(int)) df_mrr['mmr_period'] = pd.to_datetime(df_mrr['first_order']).dt.to_period('M') df_mrr['price_after_commission'] = df_mrr['Amount']*0.95 df_mrr['Amount_per_month'] = df_mrr['price_after_commission']/df_mrr['Period'] print(df_mrr.head(2)) Таблица для расчета MMR Следующим шагом создадим список всех уникальных периодов. periods = df_mrr.mmr_period.sort_values(ascending=True).unique().astype(str).tolist() Теперь мы готовы рассчитать MMR. Основная идея рассчитывать сумму с учетом даты окончания и начала подписки. Мы таким образом размажем весь платеж по периоду действия подписки. mrr=[] for mdate in periods: my_df = df_mrr[(df_mrr['EndDate'].dt.to_period('M')>mdate ) & (df_mrr['first_order'].dt.to_period('M')<= mdate)] mmrr = my_df['Amount_per_month'].sum() mrr.append({'date':mdate,'mmrr':mmrr}) Визуализируем то, что у нас получилось. dates = [x['date'] for x in mrr] y = [x['mmrr'] for x in mrr] sns.set() plt.figure(figsize=(40,10)) plt.title('MRR by month') plt.ylabel('total') plt.bar(dates, y) plt.rc('font',**{'family' : 'normal', 'weight' : 'bold', 'size' : 60}) plt.show() Визуализация MMR Видим, что у нас достаточно хороший продукт. MMR стабильно рос до апреля, затем темпы роста слегка снизились, а в сентябре видим падение. Подписки стали заканчиваться, а новых больше не стало. Проверка расчёта Давайте сделаем небольшую и наглядную проверку расчета MMR. Возьмём одного клиента customer_id = 084a0e74918bd829d509441c2504135e test_df = df_mrr[df_mrr.customer_id=='084a0e74918bd829d509441c2504135e'] mrr = [] for mdate in periods: my_df = test_df[(test_df['EndDate'].dt.to_period('M')>mdate ) & (test_df['first_order'].dt.to_period('M')<= mdate)] mmrr = my_df['Amount_per_month'].sum() mrr.append({'date':mdate,'mmrr':mmrr}) dates = [x['date'] for x in mrr] y = [x['mmrr'] for x in mrr] print(mrr) sns.set() plt.figure(figsize=(40,10)) plt.title('MRR by month') plt.ylabel('total') plt.bar(dates, y) plt.rc('font',**{'family' : 'normal', 'weight' : 'bold', 'size' : 60}) plt.show() MRR по одному клиенту Как мы видим весь доход от клиента равномерно размазался по месяцам. Заключение Разобрали расчет MMR. Конечно этот пример не самый боевой. Так в нем, например, нет примеров изменения тарифа у клиента. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Когортный анализ в Python Когортный анализ Что такое когортный анализ? Когортный анализ заключается в исследовании характеристик когорт/винтажей/поколений, объединенных по общим временным признакам. Когорта/винтаж/поколение — это группа, сформированная особым образом по временному признаку: например, месяцу регистрации, месяцу первой транзакции или первого посещения сайта. Когорты очень похожи на сегменты с тем отличием, что когорта объединяет группы определенного промежутка времени, в то время как сегмент может быть основан на любых других характеристиках. Почему это ценно? Такой анализ может быть полезен, когда речь заходит о понимании здоровья вашего бизнеса и «липкости» - лояльности ваших клиентов. «Липкость» имеет решающее значение, так как гораздо дешевле и проще удерживать клиента, чем приобретать новых. Кроме того, ваш продукт развивается с течением времени. Новые функции добавляются и удаляются, изменяется дизайн и т. д. Наблюдение отдельных групп с течением времени является отправной точкой для понимания того, как эти изменения влияют на поведение пользователя/группы. Постановка задачи Для этой задачи используем публичный датасет: https://www.kaggle.com/olistbr/brazilian-ecommerce и файлы olist_orders_dataset.csv и olist_order_payments_dataset.csv. Соединить их можно по order_id. Ответьте на два вопроса: Сколько в среднем заказов и на какую сумму делают все когорты за первый год Сравните две любые когорты по прибыле и количеству заказов Реализация когортного анализа на Python import pandas as pd import numpy as np import warnings warnings.filterwarnings("ignore") import seaborn as sns import matplotlib import matplotlib.pyplot as plt import matplotlib.ticker import matplotlib as mpl pd.set_option('max_columns', 50) mpl.rcParams['lines.linewidth'] = 2 %matplotlib inline sns.set_context( "notebook", font_scale = 1.5, rc = { "figure.figsize" : (30, 30), "axes.titlesize" : 18 } ) df_orders = pd.read_csv('data/olist_orders_dataset.csv') df_payments = pd.read_csv('data/olist_order_payments_dataset.csv') Импортируем все необходимые библиотеки и считаем файлы. Когорты мы будем строить на дату покупки (order_purchase_timestamp), поэтому преобразуем её в datetime64. Создадим индекс order_id и соединим наши датасеты по нему. df_orders['order_purchase_timestamp'] = pd.to_datetime(df_orders['order_purchase_timestamp']) df_payments = df_payments.set_index('order_id') df_orders = df_orders.set_index('order_id') order_payment = df_orders.join(df_payments) Поскольку мы делаем ежемесячные когорты, мы будем смотреть на общее ежемесячное поведение наших клиентов. Поэтому нам не нужны гранулированные данные order_purchase_timestamp. order_payment.reset_index(inplace=True) order_payment['Period'] = order_payment.order_purchase_timestamp.dt.strftime('%Y-%m') Создадим новый столбец CohortGroup, который является годом и месяцем, когда произошла первая доставка заказа клиенту. order_payment.set_index('customer_id', inplace=True) order_payment['CohortGroup'] = order_payment.groupby(level=0)['order_purchase_timestamp'].min().dt.strftime('%Y-%m')#.dt.apply(lambda x: x.strftime('%Y-%m')) order_payment.reset_index(inplace=True) Рассматриваем ежемесячные когорты, нам необходимо агрегировать клиентов, покупки и суммы покупок по каждой CohortGroup в течение месяца (Period). grouped = order_payment.groupby(['CohortGroup', 'Period']) cohorts = grouped.agg({'customer_id': pd.Series.nunique, 'payment_value': 'sum', 'order_id': 'count'}) cohorts.rename(columns={'customer_id': 'TotalClients', 'order_id': 'TotalOrders'}, inplace=True) Мы хотим посмотреть, как каждая когорта вела себя в течение нескольких месяцев после их первой покупки, поэтому нам нужно будет проиндексировать каждую когорту до их первого месяца. Например, CohortPeriod = 1 будет первым месяцем когорты, CohortPeriod = 2 является их вторым и так далее. Это позволяет нам сравнивать когорты на разных этапах их жизни. def cohort_period(df): df['CohortPeriod'] = np.arange(len(df)) + 1 return df cohorts = cohorts.groupby(level=0).apply(cohort_period) print(cohorts.head(10)) print(cohorts.tail(12)) Когорты К сожалению в этом датасете есть только первый месяц когорты. По этим результатам мы уже можем сравнивать когорты. Например когорту 2018-06 и 2018-07: Общее количество клиентов и покупок выросло. Но, давайте посчитаем покупки на клиента: 2018-06 — 6419/6167 = 1.04 2018-07 — 6507/6292 = 1.03 Вывод: в среднем клиенты стали покупать реже. В качестве домашненго задания напишите код, который посчитает покупки на клиента. Теперь посчитаем среднее количество заказов, клиентов и среднюю сумму для каждого года. cohorts = cohorts.reset_index() cohorts['CohortGroupYear'] = cohorts['CohortGroup'].apply(lambda x: x.split('-')[0]) tt = cohorts.groupby('CohortGroupYear').agg({'payment_value': 'mean','TotalOrders':'mean','TotalClients':'mean'}) tt['ratio'] = tt['TotalOrders'] / tt['TotalClients'] print(tt) Когорты по годам За 2016 год у нас к сожалению только 3 месяца с очень странными значениями, а за 2018 только 10 месяцев. Мы уже видим рост в 2018 году по сравнению к 2017, но покупки на клиента снижаются. Заключение Разобрали когортный анализ. Он позволяет нам сравнивать разные группы клиентов объеденных по какому-то признаку по времени и понимать как разные версии продукта влияют на него. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### RFM анализ в Python В моём телеграм канале я запустил новую рубрику - task. Суть рубрики - Я публикую задание каждый вторник с постановкой задачи и ссылкой на данные. Код с описанием хода решения задачи я размещаю в четверг. Задачи сделаны так, что бы на их решение нужно потратить не более пары часов. Подробный пост - https://t.me/renat_alimbekov/71 Постановка задачи Первая задача - сделать RFM-анализ. Он делит пользователей на сегменты в зависимости от давности (Recency), частоты (Frequency) и общей суммы платежей (Monetary). Recency - разница между текущей датой и датой последнего платежа Frequency - количество транзакций Monetary - сумма покупок Эти три показателя нужно рассчитать отдельно для каждого покупателя. После чего поставить оценки от 1-3 или 1-5. Чем шире диапазон, тем более узкие сегменты у нас получатся. Баллы можно выставить с использованием квантилей. Сортируем данные по одному из критериев и делим на равныегруппы. Для этой задачи используем публичный датасет: https://www.kaggle.com/olistbr/brazilian-ecommerce и файлы olist_orders_dataset.csv и olist_order_payments_dataset.csv. Соединить их можно по order_id. Реализация RFM на Python import numpy as np import pandas as pd %matplotlib inline import matplotlib import matplotlib.pyplot as plt from datetime import date,timedelta df_orders = pd.read_csv('data/olist_orders_dataset.csv') df_payments = pd.read_csv('data/olist_order_payments_dataset.csv') Импортируем все необходимые библиотеки и считаем файлы. Мы будем опираться на дату доставки заказа первозчиком (order_delivered_carrier_date), поэтому преобразуем её в datetime64. Создадим индекс order_id и соединим наши датасеты по нему. df_orders['order_delivered_carrier_date'] = pd.to_datetime(df_orders['order_delivered_carrier_date']) df_payments = df_payments.set_index('order_id') df_orders = df_orders.set_index('order_id') order_payment = df_orders.join(df_payments) Так как датасет не самый свежий, вместо текущей даты будем использовать max+1. Для создания recency, frequency и monetary мы сгруппируем наши записи по customer_id. last_date = order_payment['order_delivered_carrier_date'].max() + timedelta(days=1) rfmTable = order_payment.reset_index().groupby('customer_id').agg({'order_delivered_carrier_date': lambda x: (last_date - x.max()).days, 'order_id': lambda x: len(x), 'payment_value': lambda x: x.sum()}) rfmTable.rename(columns={'order_delivered_carrier_date': 'recency', 'order_id': 'frequency', 'payment_value': 'monetary_value'}, inplace=True) RFM анализ Теперь нам нужно выставить оценки. Мы будем разбивать на диапазон от 1 до 5. Чем шире диапазон, тем более точные наши группы, но в тоже время работать с большим количествов комбинаций сложнее. quantiles = rfmTable.quantile(q=[0.20, 0.40, 0.60, 0.80]) quantiles = quantiles.to_dict() segmented_rfm = rfmTable def RScore(x,p,d): if x <= d[p][0.20]: return 1 elif x <= d[p][0.40]: return 2 elif x <= d[p][0.60]: return 3 elif x<=d[p][0.80]: return 4 else: return 5 segmented_rfm['r_quartile'] = segmented_rfm['recency'].apply(RScore, args=('recency',quantiles,)) segmented_rfm['f_quartile'] = segmented_rfm['frequency'].apply(RScore, args=('frequency',quantiles,)) segmented_rfm['m_quartile'] = segmented_rfm['monetary_value'].apply(RScore, args=('monetary_value',quantiles,)) segmented_rfm['RFMScore'] = segmented_rfm.r_quartile.map(str) + segmented_rfm.f_quartile.map(str) + segmented_rfm.m_quartile.map(str) print(segmented_rfm.head()) RFM Score Отдельно можем посмотреть среднее значение recency по всем RFMScore. fig=plt.figure(figsize=(18, 16), dpi= 80, facecolor='w', edgecolor='k') segmented_rfm.groupby('RFMScore').agg('recency').mean().plot(kind='bar', colormap='Blues_r') plt.show() Recency Score Пока возможно это не очень информативно. Давайте попробуем понять как использовать результаты анализа. Как использовать результаты RFM анализа Цель RFM анализа сформировать сегменты и в зависимости от сегмента воздействовать на них определенным образом. Например: предложить бонус, льготу, отправить push или email уведомление. Важно делать это таргетировано. Эффект от использования RFM анализа может быть следующим: удержание клиентов, повышение дохода, повышение лояльность клиентов. Примеры интерпретации сегментов RFM анализа: R=5, F=5, M=5 - платят чаcто, много и недавно. Самые лояльным и активные пользователи. R=1, F=1, M=1 - платят мало, редко и давно. Скорее всего потерянные клиенты. Возможно не стоит предпринять действия по их возврату, если цена привлечения выше ожидаемой прибыли. R=1/2, F=4/5, M=4/5 - лояльные пользователи на грани ухода. Предлагаем им бонус, скидку и пытаемся их вернуть. R=4/5, F=1, M=1/2/3/4/5 - пользователи недавно совершили платеж. Пробуем их стимулировать покупать еще. Заключение Разобрали простой и эффективный способ сегментации пользователей/ клиентов. RFM анализ поможет вам выбрать таргетированное воздействие и таким образом повысить доход, или удержать пользователей. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Python logging HOWTO: logging vs loguru In this post we will try to choose a library for logging in Python. Logs help to record and understand what went wrong in the work of your service. Informational messages are often written to the logs. For example: parameters, quality metrics and model training progress. An example of a piece of model training log: An example of a piece of model training log logging vs loguru The Logging library is the standard Python logging solution. Logging is often criticized for the complexity of the configs, the inconvenience of setting different levels of logging and rotation of log files. Loguru, on the contrary, positions itself as the most simple library for logging in Python. Let's try to sort out the pros and cons of each library and choose the best solution for our tasks. Basic usage Compare the code for the most basic logging. We will write the log to a file. import logging logging.basicConfig(filename='logs/logs.log', level=logging.DEBUG) logging.debug('Error') logging.info('Information message') logging.warning('Warning') Analyze the code a little. basicConfig - creates a basic configuration for our logging, filename is the path to the log file, level is the logging level. When logging.DEBUG it will skip all log entries. from loguru import logger logger.add('logs/logs.log', level='DEBUG') logger.debug('Error') logger.info('Information message') logger.warning('Warning') I think everything is clear here and the code looks very similar. But let's look at the result in the file and console. DEBUG:root:Error INFO:root:Information message WARNING:root:Warning 2021-02-04 17:44:10.914 | DEBUG | main::14 - Error 2021-02-04 17:44:10.915 | INFO | main::15 - Information message 2021-02-04 17:44:10.915 | WARNING | main::16 - Warning Loguru result Both in the console and in the Loguru file it looks more informative right away by default. Formatting Let's now try to do some formatting in Logger. For this there is a method .setFormatter. We will display the time of the event, the type and the event itself as in Loguru. import logging import sys logger = logging.getLogger() logger.setLevel(logging.DEBUG) fileHandler = logging.FileHandler('logs/logs.log') fileHandler.setFormatter(logging.Formatter(fmt='[%(asctime)s: %(levelname)s] %(message)s')) logger.addHandler(fileHandler) streamHandler = logging.StreamHandler(stream=sys.stdout) streamHandler.setFormatter(logging.Formatter(fmt='[%(asctime)s: %(levelname)s] %(message)s')) logger.addHandler(streamHandler) logging.debug('Error') logging.info('Information message') logging.warning('Warning') Oh you! There is much more code. Let's take a look at the new classes and methods. First, we have a Handler class. FileHandler to write to file and StreamHandler to write to console. Then you need to use the addHandler method to transfer them to our logger. You will find a few more Handlers in the documentation. Now let's take a look at the Formatter class. From the name it is clear that this class is responsible for the format of the recording of our log. In our example, in addition to the message itself, we added the recording time and its type. Now our log looks like this: [2021-02-04 21:28:28,283: DEBUG] Error [2021-02-04 21:28:28,283: INFO] Information message [2021-02-04 21:28:28,283: WARNING] Warning Loguru also has formatting. This is done like this: logger.add ('logs / logs.log', level = 'DEBUG', format = "{time} {level} {message}") Rotation / retention / compression It is often necessary to rotate the log - that is, to archive, clear or create a new log file with a specified frequency. For example this is needed when the logs become too large. Let's compare the code again. import logging import time from logging.handlers import RotatingFileHandler def create_rotating_log(path): logger = logging.getLogger("Rotating Log") logger.setLevel(logging.INFO) handler = RotatingFileHandler(path, maxBytes=20, backupCount=5) logger.addHandler(handler) for i in range(10): logger.info("This is test log line %s" % i) time.sleep(1.5) if name == "main": log_file = "test.log" create_rotating_log(log_file) This uses RotatingFileHandler. maxBytes is the maximum file size, backupCount is how many files to store. Let's see it can be done in Loguru: logger.add("file_1.log", rotation="500 MB") # Automatically rotate too big file logger.add("file_2.log", rotation="12:00") # New file is created each day at noon logger.add("file_3.log", rotation="1 week") # Once the file is too old, it's rotated logger.add("file_X.log", retention="10 days") # Cleanup after some time logger.add("file_Y.log", compression="zip") # Save some loved space Again, everything looks simpler and more convenient. Exception Handling Logging has a separate method - exception. This is quite convenient and you need to use it in a try except block. import logging def my_function(x, y, z): return x / (y * z) try: my_function(1, 2, 0) except ZeroDivisionError: logging.exception("message") The log will look like this: ERROR:root:message Traceback (most recent call last): File "logs.py", line 5, in my_function(1, 2, 0) File "logs.py", line 3, in my_function return x / (y * z) ZeroDivisionError: division by zero In Loguru, we will need to use the @logger.catch decorator: from loguru import logger @logger.catch def my_function(x, y, z): return x / (y * z) my_function(1, 2, 0) Wow! The log looks cool. Even shows the value of the variables: Loguru exception handling Conclusion In this post, I have skimmed two libraries for logging in Python. Both libraries have a number of other features and capabilities. I recommend reading more in the documentation. I love Loguru and it is great for use in machine learning pipelines or for training neural networks. In small services, Loguru is great too. The only minus to using Loguru that I found is another extra dependency in your project. Documentation Loguru - https://github.com/Delgan/loguru Logging - https://docs.python.org/3/howto/logging.html Read more my posts ### Выбираем логирование в Python: logging vs loguru В этой заметке мы попробуем выбрать библиотеку для логирования в Python. Логи помогают зафиксировать и понять, что пошло не так в работе вашего микросервиса. Так же в логи часто пишут информационные сообщения. Например: параметры, метрики качества и ход обучения модели. Пример куска лога обучения модели: Пример куска лога обучения модели logging vs loguru Библиотека Logging является стандартным решением для логирования в Python. Logging часто критикуем за сложность конфигов, неудобство настроек разного уровня логирования и ротации файлов логов. Loguru же наоборот, позиционирует себя как максимально простая библиотека для логирования в Python. Попробуем разробрать плюсы и минусы каждой библиотеки и выбрать лучшее решение для своих задач. Базовое применение Сравним код для самого базового логирования. Будем записывать лог в файл. import logging logging.basicConfig(filename='logs/logs.log', level=logging.DEBUG) logging.debug('Error') logging.info('Information message') logging.warning('Warning') Разберем немножко код. basicConfig - создаёт базовую конфигурацию для нашего логирования, filename - путь к файлу лога, level - уровень логирования. При logging.DEBUG он будет пропускать все записи в лог. from loguru import logger logger.add('logs/logs.log', level='DEBUG') logger.debug('Error') logger.info('Information message') logger.warning('Warning') Думаю тут всё понятно и код выглядит весьма похоже. Но посмотрим на результат в файле и консоли. DEBUG:root:Error INFO:root:Information message WARNING:root:Warning 2021-02-04 17:44:10.914 | DEBUG | main::14 - Error 2021-02-04 17:44:10.915 | INFO | main::15 - Information message 2021-02-04 17:44:10.915 | WARNING | main::16 - Warning Результат Loguru И в консоли и в файле Loguru выглядит поинформативней сразу по умолчанию. Форматирование Давайте теперь попробуем сделать форматирование в Logger. Для этого есть метод .setFormatter Будем выводить время события, тип и само событие как в Loguru. import logging import sys logger = logging.getLogger() logger.setLevel(logging.DEBUG) fileHandler = logging.FileHandler('logs/logs.log') fileHandler.setFormatter(logging.Formatter(fmt='[%(asctime)s: %(levelname)s] %(message)s')) logger.addHandler(fileHandler) streamHandler = logging.StreamHandler(stream=sys.stdout) streamHandler.setFormatter(logging.Formatter(fmt='[%(asctime)s: %(levelname)s] %(message)s')) logger.addHandler(streamHandler) logging.debug('Error') logging.info('Information message') logging.warning('Warning') Ох ты ж! Кода стало гораздо больше. Давайте разберем новые классы и методы. Для начала у нас есть класс Handler. FileHandler для записи в файл и StreamHandler для запись в консоль. Затем нужно с помощью метода addHandler передать их в наш logger. В документации вы найдете еще несколько Handler. Теперь разберемся с классом Formatter. Из названия понятно, что этот класс отвечает за формат записи нашего лога. В нашем примере мы добавили помимо самого сообщения время записи и его тип. Теперь наш лог выглядит так: [2021-02-04 21:28:28,283: DEBUG] Error [2021-02-04 21:28:28,283: INFO] Information message [2021-02-04 21:28:28,283: WARNING] Warning В Loguru тоже есть форматирование. Делается это так: logger.add('logs/logs.log', level='DEBUG', format="{time} {level} {message}") Ротация / очистка / архивирование Часто возникает необходимость ротировать лог - то есть архивировать, очищать или создать новый лог файл с заданной переодичностью. Например это нужно когда логи становятся слишком большими. Снова сравним код. import logging import time from logging.handlers import RotatingFileHandler def create_rotating_log(path): logger = logging.getLogger("Rotating Log") logger.setLevel(logging.INFO) handler = RotatingFileHandler(path, maxBytes=20, backupCount=5) logger.addHandler(handler) for i in range(10): logger.info("This is test log line %s" % i) time.sleep(1.5) if name == "main": log_file = "test.log" create_rotating_log(log_file) Тут используется RotatingFileHandler. maxBytes - максимальный размер файла, backupCount - сколько файлов хранить. Посмотрим как это можно сделать в Loguru: logger.add("file_1.log", rotation="500 MB") # Пишет в новый файл после достижения размера лога 500 MB logger.add("file_2.log", rotation="12:00") # В 12:00 создаёт новый файл logger.add("file_X.log", retention="10 days") # Очищает наш лог после 10 дней logger.add("file_Y.log", compression="zip") # Архивирует наши логи Опять всё выглядит попроще и удобнее. Обработка исключений В Logging есть отдельный метод - exception. Это достаточно удобно и нужно применять его в блоке try except. import logging def my_function(x, y, z): return x / (y * z) try: my_function(1, 2, 0) except ZeroDivisionError: logging.exception("message") Лог будет выгледеть так: ERROR:root:message Traceback (most recent call last): File "logs.py", line 5, in my_function(1, 2, 0) File "logs.py", line 3, in my_function return x / (y * z) ZeroDivisionError: division by zero В Loguru нам будет нужно использовать декоратор @logger.catch: from loguru import logger @logger.catch def my_function(x, y, z): return x / (y * z) my_function(1, 2, 0) Вау! Лог выглядит круто. Даже показывает значение переменных: Loguru обработка исключений Заключение В этой заметке достаточно бегло рассмотрели две библиотеки для логирования в Python. Обе библиотеки имеют еще ряд фишек и возможностей. Рекомендую подробнее почитать в документации. Мне нравится Loguru и он отлично подходит для использования в пайплайнах машинного обучения или для тренировок нейронных сетей. В небольших микросервисах Loguru тоже отлично подходит. Единственный минус использования Loguru, который я нашел это еще одна лишняя зависимость в вашем проекте. Документация Loguru - https://github.com/Delgan/loguru Logging - https://docs.python.org/3/howto/logging.html Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Machine Learning Models in production: Flask and REST API A trained machine learning model alone will not add value for business. The model must be integrated into the company's IT infrastructure. Let's develope REST API microservice to classify Iris flowers. The dataset consists of the length and width of two types of Iris petals: sepal and petal. The target variable is Iris variety: 0 - Setosa, 1 - Versicolor, 2 - Virginica. Saving and loading a model Before moving on to develope API, we need to train and save the model. Take the RandomForestClassifier model. Now let's save the model to a file and load it to make predictions. This can be done with pickle or joblib. import pickle filename = 'model.pkl' pickle.dump(clf, open(filename, 'wb')) We'll use pickle.load to load and validate the model. loaded_model = pickle.load(open(filename, 'rb')) result = loaded_model.score(X_test, y_test) print(result) The code for training, saving and loading the model is available in the repository — link What is REST API and microservices Microservice is a web service that decides one business need and can interact with other services in the IT infrastructure using, for example, HTTP. An architecture consisting of several microservices is called a microservice architecture. REST (Representational State Transfer) - the principles of organizing the interaction of services through the HTTP protocol. Clients send requests using the methods provided by the HTTP protocol and perform the operation. For example: getting, adding, modifying or deleting data. API (Application Programming Interface) — interface for communication between services. Microservice design Let's move on to practice to make it clearer. We will design our service. Service structure: rest_api.py — Flask application that interacts with the client and returns a model prediction model.py — file with functions for loading models models/ — folder with saved models logs/ —folder with logs The API will be accessed at the following URL— http://[hostname]/iris/api/v1.0/getpred The URL includes the application name and API version. The application name identifies the service. The API version is useful if there are new versions of the service, but you need to keep the old call. This may be necessary for testing or the API is different for different systems. Next, create http://[hostname]/iris/api/v1.0/status/ to check the status of the request to the service and http://[hostname]/iris/api/v1.0/result/ to get the results models. Let's create a template of our service. import os from flask import Flask, jsonify, abort, make_response, request import requests import json import time import sys import pandas as pd app = Flask(__name__) def launch_task(sepal_length, sepal_width, petal_length, petal_width, api): print(sepal_length, sepal_width, petal_length, petal_width, api) if api == 'v1.0': res_dict = {'Done': 'API exist'} return res_dict else: res_dict = {'error': 'API doesnt exist'} return res_dict @app.route('/iris/api/v1.0/getpred', methods=['GET']) def get_task(): result = launch_task(request.args.get('sepal_length'), request.args.get('sepal_width'), \ request.args.get('petal_length'), request.args.get('petal_width'), 'v1.0') return make_response(jsonify(result), 200) if __name__ == '__main__': app.run(port=5000, debug=True) The model is not used yet. I will note a few points - the get_task function uses the GET method and receives the features necessary for the model to work as input. The call to our service looks like this: http://[hostname]/iris/api/v1.0/getpred?sepal_length=5.1&sepal_width=3.5&petal_length=1.4&petal_width=0.2 The launch_task function will already work with the model, but for now it simply checks the availability of the API version and prints the parameters passed to it to the console. Let's make sure everything works. Let's run our application in the console: python rest_api.py Let's turn in the browser at http://127.0.0.1:5000/iris/api/v1.0/getpred?sepal_length=5.1&sepal_width=3.5&petal_length=1.4&petal_width=0.2 and see in the browser and console that everything works fine. Testing our API Testing our API in the console The template is ready, we will tune it. Error handling Notice the line return make_response (jsonify (result), 200). 200 is the HTTP status code "OK". In real life, errors can occur in the service, so let's create error handling. We will handle two common errors: 404 - "Not Found" and 500 - "Internal Server Error" @app.errorhandler(404) def not_found(error): return make_response(jsonify({'code': 'PAGE_NOT_FOUND'}), 404) @app.errorhandler(500) def server_error(error): return make_response(jsonify({'code': 'INTERNAL_SERVER_ERROR'}), 500) Working with the model Let's create a model.py file to load the trained model. import pickle PATH_TO_MODELS = 'models/' filename = 'model.pkl' model = PATH_TO_MODELS + filename def load_model(): loaded_model = pickle.load(open(model, 'rb')) return loaded_model Now it's time to add the launch_task function to return the predictions made by the model. model = M.load_model() targets = ['setosa', 'versicolor', 'virginica'] def get_pred(sepal_length, sepal_width, petal_length, petal_width): all_columns = ['sepal length', 'sepal width', 'petal length', 'petal width'] lst = [sepal_length, sepal_width, petal_length, petal_width] df = pd.DataFrame([lst], columns = all_columns) df = df.astype(float) result = model.predict_proba(df) predx = ['%.3f' % elem for elem in result[0]] preds_concat = pd.concat([pd.Series(targets), pd.Series(predx)], axis=1) preds = pd.DataFrame(data=preds_concat) preds.columns = ["class", "probability"] return preds.reset_index(drop=True) def launch_task(sepal_length, sepal_width, petal_length, petal_width, api): pred_model = get_pred(sepal_length, sepal_width, petal_length, petal_width) if api == 'v1.0': res_dict = {'result': json.loads( pd.DataFrame(pred_model).to_json(orient='records'))} return res_dict else: res_dict = {'error': 'API doesnt exist'} return res_dict Added model loading and get_pred function, which, based on the obtained feature values, returns a dataframe with the name of the Iris variety and the probability of belonging to the class. The launch_task now returns a serialized JSON response. Serialized JSON response It would seem that the service is ready. Yes this is true. But let's work on it some more Logging Let's implement logging in a microservice. Key points and errors during the microservice operation will be recorded in the log. Logging is implemented using the logging library. import logging logging.basicConfig(filename='logs/logs.log',level=logging.DEBUG) Next, in the necessary places of the service, put an entry in the log. logging.debug('Error') logging.info('Information message') logging.warning('Warning') The log looks like this Log Redis based task queue In our example, the model runs quickly. Imagine that the model is working with an image, video or text. The model will take a little more time to run. For example: 3-10 seconds. This means the client is waiting for the service response. Therefore, the execution must be made async. That is, the service does not wait for the process to complete, but continues to work independently. Unfortunately Flask does not support async work, so we will use the Python RQ tool. RQ stands for Redis Queue, the tool runs on Redis. Remember, RQ will not work under Windows. How will it work? The client call the microservice, the service fixes the job_id, and the model processes the request in the background. You can find out about the status of the request at http://[hostname]/iris/api/v1.0/status/, using job_id. If the status is success, then at the address http://[hostname]/iris/api/v1.0/result, also by job_id get the result of the model execution. from rq import Queue, get_current_job from redis import Redis redis_conn = Redis(host='app-redis', port=6379) queue = Queue('rest_api', connection=redis_conn, default_timeout=1200) The execution timeout is set using default_timeout. Here 1200 seconds are set to execute for tasks that fall into the queue with the name rest_api. Let's start the queue with the command rq worker rest_api For the microservice to work, run a sufficient number of workers to process. If there are few workers, tasks will be queued and executed as they become free. Let's modify our get_task function to launch launch_task using a queue. def get_response(dict, status=200): return make_response(jsonify(dict), status) def get_job_response(job_id): return get_response({'job_id': job_id}) @app.route('/iris/api/v1.0/getpred', methods=['GET']) def get_task(): job_id = request.args.get('job_id') job = queue.enqueue('rest_api.launch_task', request.args.get('sepal_length'), request.args.get('sepal_width'), \ request.args.get('petal_length'), request.args.get('petal_width'), 'v1.0', job_id, result_ttl=60 * 60 * 24, \ job_id=job_id) return get_job_response(job.get_id()) Note that now another additional parameter is passed to launch_task - job_id. The result_ttl parameter is responsible for the storage period of the result. The value is transmitted in seconds. In the example, the shelf life is one day. Now, when starting the microservice in the browser, the job_id is returned. job_id when starting the service Now let's implement a check of the execution status of the model. JSON will be returned in the following format: code — answer code. 404 — OT_FOUND, PAGE_NOT_FOUND. 505 — INTERNAL_SERVER_ERROR. 200 — READY. 202 — NOT_READY status — success/error/running def get_process_response(code, process_status, status=200): return get_response({ 'code': code, 'status': process_status }, status) @app.route('/iris/api/status/') def status(id): job = queue.fetch_job(id) if (job is None): return get_process_response('NOT_FOUND', 'error', 404) if (job.is_failed): return get_process_response('INTERNAL_SERVER_ERROR', 'error', 500) if (job.is_finished): return get_process_response('READY', 'success') return get_process_response('NOT_READY', 'running', 202) Using job_id you can find out the execution status of the model. For example: http://[hostname]/iris/api/v1.0/status/[job_id] Check status It remains to implement this to obtain the result of the model. If processing is not completed, the function returns Not ready, 202. If processed, it returns JSON with information about the name of the Iris variety and the probability of belonging to the class. @app.route('/iris/api/result/') def result(id): job = queue.fetch_job(id) if job is None: return get_process_response('NOT_FOUND', 'error', 404) if job.is_failed: return get_process_response('INTERNAL_SERVER_ERROR', 'error', 500) if job.is_finished: job_result = copy.deepcopy(job.result) result = { 'result': job_result['result'] } return get_response(result) return get_process_response('NOT_FOUND', 'error', 404) In the same way, using job_id, we get the result of the model execution. For example: http://[hostname]/iris/api/v1.0/result/[job_id] The result of the microservice The microservice is now ready for integration with the IT infrastructure. Integration with IT infrastructure Let's generate a requirements.txt file based on the modules and packages that you import into your project. You can of course do it manually. Better yet, we'll use pipreqs to automatically generate Python dependencies. Install pipreqs pip install pipreqs Launch pipreqs // Done The result of pipreqs Unfortunately, you will have to change the file manually. Let's add gunicorn there, which will come in handy. But more on that later. add scikit_learn to make the model work. The scikit_learn version should be the one the model is trained on. You can check the version like this: import sklearn print('The scikit-learn version is {}.'.format(sklearn.__version__)) The content of the file looks like this: Contents of the requirements.txt file Now let's package the entire microservice in Docker. Docker is software for automating the deployment and management of applications in containerized environments. Why Docker? The main advantage is fast deployment. Docker creates a container for each process and does not boot the OS. Everything happens in seconds. Insulation and safety. With Docker, resources are isolated and shared. You can not be afraid to remove containers, the removal will be complete and clean. Only the assigned resources are used. Another advantage is the de facto standardization of the approach. Almost all large companies build their infrastructure using Docker. Standardization reduces the amount of time spent on defects and increases the amount of time available to develop features. Create Dockerfile: FROM python:3.7-buster RUN apt-get update -y WORKDIR /usr/src/app ENV LANG C.UTF-8 COPY requirements.txt ./ RUN pip install -r requirements.txt COPY . . Let's analyze each line: FROM python:3.7-buster — base image RUN apt-get update -y — Update information about repositories inside the container WORKDIR /usr/src/app — Change the working directory inside the container. The commands will then be run inside the /usr/src/ app directory inside the container ENV LANG C.UTF-8 — Set the locale inside the container COPY requirements.txt ./ — copy our file with dependencies RUN pip install -r requirements.txt — Install dependencies saved in requirements.txt COPY . . — copy the new code to the container file system Now let's create a docker-compose.yml file to define a set of services. version: '3' services: iris: build: . image: iris:1.0 container_name: iris ports: - 5000:5000 extra_hosts: - "app-redis:[your IP]" command: /usr/src/app/start.sh What you should pay attention to here: command - launches the start.sh file. About it a little later. extra_hosts adds hostname mappings to work with Redis. If you want to test locally, then specify the IP of your computer. Go to file start.sh #!/bin/bash run_rq() { rq worker rest_api -u 'redis://app-redis:6379' 2>&1 | tee -a & } run_gunicorn() { gunicorn rest_api:app -b 0.0.0.0:5000 --workers=2 2>&1 | tee -a } run_rq run_gunicorn This script starts the already familiar queue worker and starts our microservice using Gunicorn. Gunicorn is a WSGI server built for use on UNIX systems. This server is relatively fast, resource intensive, easy to start, and works with a wide variety of web frameworks. Let's test, run the command to create the container docker-compose build Launch docker-compose up Running and ready to test. Docker container testing Docker was launched to test the health of the container. In production, do it right away: docker-compose up -d --build --force-recreate The -d flag is for running the container in the background. Conclusion In this note, I managed to consider a large stack of technologies. We got acquainted with the microservice architecture, created a template for the Flask microservice, logged the operation of the service and got acquainted with the task queue based on Redis. We separately considered the integration of the solution into the IT infrastructure using Docker. This note is not intended to be complete, but it allows you to quickly create microservices from this template. This template is suitable both for working with tabular data and for computer vision tasks. Link to the repository with the code from the note Read more my posts ### How to make your CV attractive with a pet project For junior Date Scientists, a CV consists of courses taken, education, and possibly not the most relevant work experience. Such resumes are not much different from the bulk of job seekers. Working on a pet project is a great opportunity to improve skills. If you add the implemented pet-project to the CV, it will immediately become attractive and a topic for conversation at the interview will appear. So what is a pet-project? Pet-project is a project that is done for yourself. It is created outside of work and is often self-interested. For example: sports, electronics, food preparation, auto, travel, medicine, etc. The project will help expand professional skills and learn new ones that will be useful in work. Here are some ideas for projects in Data Science that you can get started with: Classificate Parkinson's Disease Dataset - https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons Task - Build a model that determines the presence of Parkinson's disease in humans. What you will learn: Working with tabular data Working with Gradient Boosting Libraries. For example: XGBoost Work with platforms to host the service online. For example: Heroku Create a website that will be able to determine the presence of Parkinson's disease in a person based on the questions asked. Model output to production. Dataset for determining the presence of Parkinson's disease Telegram channels analytics system Dataset - you need to collect it yourself using the telegram API The task is to create a service that parses the specified telegram channel and provides useful analytics. What you will learn: Working with the telegram API Work with text Libraries: pandas, nltk, pymorphy2, spacy and others Work with platforms to host the service online. For example: Heroku Create a website that provides useful analytics based on the specified channel name. The code for the parser and analytics can be found here The plot of the dynamics of posts in the telegram channel Background generation of music albums Dataset - you need to collect it yourself, using cover parsing, album descriptions. For example, you can use the Spotify API. The task is to generate the cover of a music album by genre. What you will learn: Working with GAN Working with Spotify API, beautifulsoup, selenium to parse data Libraries: pytorch / keras / tf, openCV and others Work with platforms to host the service online. For example: Heroku Comparison of original covers with generated Paper on this topic - https://ryanmcconville.com/publications/AlbumCoverGenerationFromGenreTags.pdf Air pollution Dataset - you need to collect it yourself or if you use open ones. For example, data from the site https://airkaz.org/ with sensor readings is available.For more recent data, contact the site creator. The task is to do useful data analysis, make a model, determine the trend, seasonality, add external linked data. For example, the weather. What you will learn: Working with time series. Libraries: pandas, seaborn, folium, fbprophet and others Make an interactive service using, for example, Heroku and https://www.streamlit.io/ Map of Almaty with sensor marks and average measurement of air pollution The code is available - https://github.com/alimbekovKZ/jupyter_notebooks_2/tree/master/airkaz Action plan Come up with a project on any topic. An action plan might look something like this: Find data. Data can be either ready-made from open sources or collected from the Internet. I recommend collecting the data yourself. This will develop parsing skills and the use of tools such as selenium and beautifulsoup Label data if necessary Train machine learning models / do automated analytics Implement a service for the machine learning model to work. I recommend looking aside - https://www.streamlit.io/ Host a service on a platform, for example: Heroku In addition to reading, an article on the pet-project topic - https://habr.com/ru/company/ods/blog/335998/ After the implementation of the project, there will be something to show to a potential employer and it will be possible to have a substantive conversation about the skills and experience that they acquired while doing the project. Read more my posts ### How To Learn a Data Science - my experience Overview of online courses to enter the Data Scientist profession. All courses are completed and a subjective view and experience is described. Only English language courses are included in this note. How To Learn a Data Science Classic ML HSE Advanced Machine Learning Specialization The specialization consists of 7 courses. I only completed 2 and they are two different experiences. Course - How to Win a Data Science Competition: Learn from the Best Kagglers, I loved it. Don't be confused by the name, the course gives you very practical things. For example, working with features, mean encoding, EDA and searching for leaks in data. Greatly expands your skillset and perspective on working with data. I highly recommend it. Course - Natural Language Processing, I got a neutral impression of it. The course gives NLP very extensively and deeply, but when doing assignments and tests, you have to google and read a lot. The course seemed difficult, and the goal was just to get into NLP, but do not forget that the specialization is called Advanced Machine Learning. I recommend it if you already have basic knowledge of NLP. DataCamp  The only paid platform in the review. Frequent discounts allow you to buy for $ 99 annual access to all courses. The platform has courses in Python, R, SQL. The site has career tracks, for example Data Scientist with Python. It was consists of 26 courses - Python, visualization, ml stack of Python libraries, classic ML, a little Deep Learning. The main advantage of courses on DataCamp is that you can quickly get skills of writing simple and basic Python code. Deep Learning Back-propagation EE-559 - Deep Learning course from École Polytechnique Fédérale de Lausanne, Switzerland The course I started with Deep Learning and Pytorch. It covers all areas of work with neural networks: computer vision, NLP, GAN. The course consists of video materials, presentations, lectures and assignments on Pytorch. The material very good introduces the theory of machine learning and neural networks. In my opinion, this part is the most interesting and thoughtful part. There, a lot of attention is paid to mathematics and formulas. I highly recommend it. AI for Medical Diagnosis Andrew Ng What you shouldn't expect from the course: an explanation of the basics of neural networks, a story about how to train best networks. Only in one task you will have write code to train the unet network, but it does not have to be run to complete the task. All exercises are writing code (Keras) into a ready-made jupiter notebooks in a marked place. Many things, such as GradCam, do not explain at all, but they just let you run it and see the result. On the plus side, there is a good section on model evaluation. Good, because they give you code that you can reuse yourself. I was too lazy to write this. If you have already taken courses or know how to use neural networks, then AI for Medical Diagnosis will be a good addition. Provided that the topic of medicine is interesting to you. Wouldn't recommend. Post in Russian with a list of courses ### Machine learning в продакшн — Flask REST API Обученная модель машинного обучения сама по себе пользу бизнесу не принесет. Модель должна быть интегрирована в IT инфраструктуру компании. Рассмотрим реализацию REST API микросервиса на примере задачи классификации цветов Ирисов. Набор данных состоит из длины и ширины двух типов лепестков Ириса: sepal и petal. Целевая переменная — это сорт Ириса: 0 — Setosa, 1 — Versicolor, 2 — Virginica. Сохранение и загрузка модели Прежде чем переходить к реализации нашего API надо обучить и сохранить модель. Возьмем модель RandomForestClassifier. Теперь сохраним модель в файл и загрузим, чтобы делать прогнозы. Это можно сделать с помощью pickle или joblib. Рассмотрим pickle, вариант с joblib останется для самостоятельного разбора. import pickle filename = 'model.pkl' pickle.dump(clf, open(filename, 'wb')) Для загрузки и проверки модели воспользуемся pickle.load loaded_model = pickle.load(open(filename, 'rb')) result = loaded_model.score(X_test, y_test) print(result) Код обучения, сохранения и загрузки модели доступен в репозитории — ссылка Что такое REST API и микросервисы Микросервис — веб-сервис, который выполняет одну бизнес-потребность и может взаимодействовать с другими сервисами в IT инфраструктуре использую, например HTTP. Архитектура, состоящая из нескольких микросервисов называется микросервисной. REST (Representational State Transfer) — принципы организации взаимодействия сервисов посредством протокола HTTP. Клиенты отправляют запросы, используя методы представленные протоколом HTTP, и выполняют операцию. Например: получение, добавление, модификация или удаление данных. API (Application Programming Interface) — интерфейс для общения сервисов. Проектируем микросервис Перейдем к практике, что бы стало понятнее. Спроектируем наш сервис. Структура сервиса: rest_api.py — приложение Flask, которое взаимодействует с клиентом и возвращает предсказание модели model.py — файл с функциями загрузки моделей models/ — папка с сохранёнными моделями logs/ — папка с логами Доступ к API будет осуществляться по-следующему URL — http://[hostname]/iris/api/v1.0/getpred В URL включено имя приложения и версия API. Имя приложения позволяет идентифицировать сервис. Версия API пригодится если будут новые версии сервиса, но нужно сохранить старый вызов. Это может быть нужно при тестировании или API различаются для разных систем. Еще создадим http://[hostname]/iris/api/v1.0/status/ для проверки статуса выполнения запроса к сервису и http://[hostname]/iris/api/v1.0/result/ для получения результаты работы модели. Cоздадим каркас нашего сервиса. import os from flask import Flask, jsonify, abort, make_response, request import requests import json import time import sys import pandas as pd app = Flask(__name__) def launch_task(sepal_length, sepal_width, petal_length, petal_width, api): print(sepal_length, sepal_width, petal_length, petal_width, api) if api == 'v1.0': res_dict = {'Done': 'API exist'} return res_dict else: res_dict = {'error': 'API doesnt exist'} return res_dict @app.route('/iris/api/v1.0/getpred', methods=['GET']) def get_task(): result = launch_task(request.args.get('sepal_length'), request.args.get('sepal_width'), \ request.args.get('petal_length'), request.args.get('petal_width'), 'v1.0') return make_response(jsonify(result), 200) if __name__ == '__main__': app.run(port=5000, debug=True) Пока модель не используется. Отмечу несколько моментов — функция get_task использует метод GET и на вход получает необходимые для работы модели признаки. Таким образом обращение к нашему сервису выглядит следующим образом: http://[hostname]/iris/api/v1.0/getpred?sepal_length=5.1&sepal_width=3.5&petal_length=1.4&petal_width=0.2 Функция launch_task будет уже работать с моделью, а пока просто проверяет доступность версии API и выводит в консоль переданные в неё параметры. Убедимся, что всё работает. Запустим в консоли наше приложение: python rest_api.py Обратимся в браузере по адресу http://127.0.0.1:5000/iris/api/v1.0/getpred?sepal_length=5.1&sepal_width=3.5&petal_length=1.4&petal_width=0.2 и видим в браузере и консоли, что всё прекрасно работает. Тестируем наш API Тестируем наш API в консоли Каркас готов, будем его дорабатывать. Обработка ошибок Обратите внимание, на строку return make_response(jsonify(result), 200). 200 — это код состояния HTTP — «Ок». В реальности, в работе сервиса могут возникнуть ошибки, поэтому создадим обработку ошибок. Будем обрабатывать две часто встречающихся ошибки: 404 — «Не найдено» и 500 — «внутренняя ошибка сервера». @app.errorhandler(404) def not_found(error): return make_response(jsonify({'code': 'PAGE_NOT_FOUND'}), 404) @app.errorhandler(500) def server_error(error): return make_response(jsonify({'code': 'INTERNAL_SERVER_ERROR'}), 500) Работаем с моделью Создадим файл model.py для загрузки обученной модели. import pickle PATH_TO_MODELS = 'models/' filename = 'model.pkl' model = PATH_TO_MODELS + filename def load_model(): loaded_model = pickle.load(open(model, 'rb')) return loaded_model Теперь пора дописать функцию launch_task, что бы возвращались предсказания сделанные моделью. model = M.load_model() targets = ['setosa', 'versicolor', 'virginica'] def get_pred(sepal_length, sepal_width, petal_length, petal_width): all_columns = ['sepal length', 'sepal width', 'petal length', 'petal width'] lst = [sepal_length, sepal_width, petal_length, petal_width] df = pd.DataFrame([lst], columns = all_columns) df = df.astype(float) result = model.predict_proba(df) predx = ['%.3f' % elem for elem in result[0]] preds_concat = pd.concat([pd.Series(targets), pd.Series(predx)], axis=1) preds = pd.DataFrame(data=preds_concat) preds.columns = ["class", "probability"] return preds.reset_index(drop=True) def launch_task(sepal_length, sepal_width, petal_length, petal_width, api): pred_model = get_pred(sepal_length, sepal_width, petal_length, petal_width) if api == 'v1.0': res_dict = {'result': json.loads( pd.DataFrame(pred_model).to_json(orient='records'))} return res_dict else: res_dict = {'error': 'API doesnt exist'} return res_dict Добавлена загрузка модели и функция get_pred, которая по полученным значениям признака возвращает датафрейм c именем сорта Ириса и вероятностью принадлежности к классу. В launch_task теперь возвращается сериализованный ответ в формате JSON. Сериализованный ответ в формате JSON Казалось бы сервис готов. Да это действительно так. Но давайте еще поработаем над ним. Логирование Реализуем логирование в микросервисе. В лог будут фиксироваться ключевые моменты и ошибки при работе микросервис. Логирование реализуется с помощью библиотеки logging. import logging logging.basicConfig(filename='logs/logs.log',level=logging.DEBUG) Далее в необходимых местах сервиса проставьте запись в лог. logging.debug('Ошибка') logging.info('Информационное сообщение') logging.warning('Предупреждение') Лог выглядит следующим образом Лог Очередь задач на базе Redis В нашем примере модель отрабатывает быстро. А представьте, что модель работает с изображением, видео или текстом. Выполнение модели потребует чуть большего времени. Например: 3–10 секунд. Это значит клиент дожидается ответа сервиса. Поэтому выполнение нужно сделать асинхронным. То есть сервис не ждёт завершения процесса, а продолжает работу независимо. К сожалению, Flask не поддерживает асинхронную работу, поэтому будем использовать инструмент Python RQ. RQ обозначает Redis Queue, инструмент работает на Redis. Помните — под Windows RQ работать не будет. Как это будет работать? Клиент обращается в микросервис, сервис фиксирует job_id, модель в фоновом режиме обрабатывает запрос. Узнать о статусе запроса можно по адресу http://[hostname]/iris/api/v1.0/status/, используя job_id. В случае если статус — success, то по адресу http://[hostname]/iris/api/v1.0/result, так же по job_id получить результат выполнения модели. from rq import Queue, get_current_job from redis import Redis redis_conn = Redis(host='app-redis', port=6379) queue = Queue('rest_api', connection=redis_conn, default_timeout=1200) Таймаут на выполнение задается с помощью default_timeout. Тут заданы 1200 секунд на выполнение для задач, попадающих в очередь с названием rest_api. Запустим очередь командой rq worker rest_api Для работы микросервиса запустите достаточное количество воркеров для обработки. В случае если воркеров мало, задачи будут вставать в очередь и выполняться по мере освобождения. Модифицируем нашу функцию get_task для запуска launch_task с использованием очереди. def get_response(dict, status=200): return make_response(jsonify(dict), status) def get_job_response(job_id): return get_response({'job_id': job_id}) @app.route('/iris/api/v1.0/getpred', methods=['GET']) def get_task(): job_id = request.args.get('job_id') job = queue.enqueue('rest_api.launch_task', request.args.get('sepal_length'), request.args.get('sepal_width'), \ request.args.get('petal_length'), request.args.get('petal_width'), 'v1.0', job_id, result_ttl=60 * 60 * 24, \ job_id=job_id) return get_job_response(job.get_id()) Обратите внимание, что теперь в launch_task передаётся еще один дополнительный параметр — job_id. Параметр result_ttl отвечает за срок хранения результата. Значение передаётся в секундах. В примере срок хранения одни сутки. Теперь при запуске микросервиса в браузере возвращается job_id. job_id при запуске сервиса Теперь реализуем проверку статуса выполнения модели. Возвращаться JSON будет в следующем формате: code — код ответа. 404 — OT_FOUND, PAGE_NOT_FOUND. 505 — INTERNAL_SERVER_ERROR. 200 — READY. 202 — NOT_READY status — success/error/running def get_process_response(code, process_status, status=200): return get_response({ 'code': code, 'status': process_status }, status) @app.route('/iris/api/status/') def status(id): job = queue.fetch_job(id) if (job is None): return get_process_response('NOT_FOUND', 'error', 404) if (job.is_failed): return get_process_response('INTERNAL_SERVER_ERROR', 'error', 500) if (job.is_finished): return get_process_response('READY', 'success') return get_process_response('NOT_READY', 'running', 202) Используя job_id можно узнать статус выполнения модели. Например: http://[hostname]/iris/api/v1.0/status/[job_id] Проверка статуса Осталось это реализовать получение результата работы модели. В случае, если обработка не завершена, функция возвращает Not ready, 202. Если обработаны возвращает JSON с информацией об имени сорта Ириса и вероятностью принадлежности к классу. @app.route('/iris/api/result/') def result(id): job = queue.fetch_job(id) if job is None: return get_process_response('NOT_FOUND', 'error', 404) if job.is_failed: return get_process_response('INTERNAL_SERVER_ERROR', 'error', 500) if job.is_finished: job_result = copy.deepcopy(job.result) result = { 'result': job_result['result'] } return get_response(result) return get_process_response('NOT_FOUND', 'error', 404) Таким же образом с помощью job_id получим результат выполнения модели. Например: http://[hostname]/iris/api/v1.0/result/[job_id] Результат работы микросервиса Теперь микросервис готов для интеграции с IT инфраструктурой. Интеграция с IT инфраструктурой Сгенерируем файл requirements.txt на основе модулей и пакетов, которые вы импортируете в свой проект. Конечно, можно сделать это вручную. Но лучше мы воспользуемся pipreqs для автоматического создания зависимостей Python. Устанавливаем pipreqs pip install pipreqs Запускаем pipreqs // Готово Результат раброты pipreqs К сожалению, придется изменить файл вручную. Добавим туда gunicorn, который еще пригодится. Но об этом позже. scikit_learn тоже добавим для работы модели. Версия scikit_learn должна быть той, на которой модель обучена. Проверить версию можно так: import sklearn print('The scikit-learn version is {}.'.format(sklearn.__version__)) Содержание файла выглядит так: Содержание файла requirements.txt Теперь упакуем весь микросервис в Docker. Docker — это программное обеспечение для автоматизации развёртывания и управления приложениями в средах с поддержкой контейнеризации. Почему Docker? Основной плюс, быстрое развертывание. Docker создает контейнер для каждого процесса и не загружает ОС. Всё происходит за секунды. Изоляция и безопасность. При использовании Docker ресурсы изолированы и разделены. Можно не боятся удалять контейнеры, удаление будет полным и чистым. Используются только назначеные ресурсы. Еще одно преимущество де-факто стандартизация подхода. Почти у всех крупных компаний инфраструктура строится с использованием Docker. Благодаря стандартизации уменьшается количество времени, потраченного на дефекты, и увеличивает количество времени, доступного для разработки функций. Создаем Dockerfile следующего содержания: FROM python:3.7-buster RUN apt-get update -y WORKDIR /usr/src/app ENV LANG C.UTF-8 COPY requirements.txt ./ RUN pip install -r requirements.txt COPY . . Разберем каждую строчку: FROM python:3.7-buster — базовый образ RUN apt-get update -y — Обновить информацию о репозиториях внутри контейнера WORKDIR /usr/src/app — Сменить рабочую директорию внутри контейнера. Команды далее будут запускаться внутри директории /usr/src/app внутри контейнера ENV LANG C.UTF-8 — Устанавливаем языковой стандарт внутри контейнера COPY requirements.txt ./ — копируем наш файл с зависимостями RUN pip install -r requirements.txt — Установить зависимости, сохраненные в requirements.txt. COPY . . — копируем новый код в файловую систему контейнера Теперь создадим файл docker-compose.yml для определения набора сервисов. version: '3' services: iris: build: . image: iris:1.0 container_name: iris ports: - 5000:5000 extra_hosts: - "app-redis:[your IP]" command: /usr/src/app/start.sh На что тут стоит обратить внимание: command — запускает файл start.sh О нём чуть позже. extra_hosts добавляет сопоставления имен хостов.Это нужно для работы с Redis. Если хотите протестировать локально, то укажите IP вашего компьютера. Переходим к файлу start.sh #!/bin/bash run_rq() { rq worker rest_api -u 'redis://app-redis:6379' 2>&1 | tee -a & } run_gunicorn() { gunicorn rest_api:app -b 0.0.0.0:5000 --workers=2 2>&1 | tee -a } run_rq run_gunicorn В этом скрипте запускаются уже знакомый воркер для очереди и запускаем наш микросервис с помощью Gunicorn. Gunicorn — это WSGI-сервер, созданный для использования в UNIX-системах. Этот сервер относительно быстрый, ресурсоёмкий, легко запускается и работает с широким спектром веб-фреймворков. Протестируем, запускаем команду для создания контейнера docker-compose build Теперь запускаем docker-compose up Работает и готово к запуску. Тестирование контейнера Docker Таким образом запускался Docker, что бы протестировать работоспособность контейнера. В продакшене сделайте сразу так: docker-compose up -d --build --force-recreate Флаг -d предназначен для запуска контейнера в фоновом режиме. Заключение В этой заметке получилось рассмотреть большой стэк технологий. Познакомились с микросервисной архитектурой, создали каркас для микросервиса Flask, логируем работу сервиса и познакомились с очередью задач на базе Redis. Отдельно рассмотрели интеграцию решения в ИТ инфрастуктуру с помощью Docker. Эта заметка не претендует на полноту, но позволяет быстро создавать из этого каркаса микросервисы. Этот каркас подходит как для работы с табличными данными, так и для задач компьютерного зрения. Дополнительный материал Мега-Учебник Flask Python-RQ: очередь задач на базе Redis Полное практическое руководство по Docker: с нуля до кластера на AWS Ссылка на репозиторий с кодом из заметки Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Как сделать резюме привлекательным с помощью pet project У начинающих Дата Саентистов резюме состоит из пройденных курсов, образования и возможно не самого релевантного опыта работы. Такие резюме мало чем отличаются от основной массы соискателей. Работа над pet project отличная возможность прокачать навыки. Если добавить в резюме реализованный pet-project оно сразу станет привлекательным и появится тема для разговора на интервью. Так, что же такое pet-project? Pet-project — это проект, который делается ради себя. Он создается вне работы и часто связан с личным интересом. Например: спорт, электроника, приготовление еды, автомобили, путешествия, медицина и т.д. Проект поможет расширить профессиональные навыки и научиться новым, которые пригодятся в работе. Вот несколько идей для проектов в Data Science, к реализации которых уже можно приступить: Обнаружение болезни Паркинсона Датасет — https://archive.ics.uci.edu/ml/machine-learning-databases/parkinsons/ Задача — Построить модель, которая определяет наличие болезни Паркинсона у человека. Чему научитесь: Работа с табличными данными Работа с библиотеками градиентного бустинга. Например: XGBoost Работать с платформами для размещения сервиса онлайн. Например: Heroku Делать сайт, который сможет по заданным вопросам определять наличие болезни Паркинсона у человека. Вывод модели в продакшн. Датасет для определения наличия болезни Паркинсон Система аналитики телеграм каналов Датасет — нужно собрать самим, используя API telegram Задача — сделать сервис, который парсит заданный телеграм канал и выдаёт полезную аналитику. Чему научитесь: Работа с API telegram Работа с текстом Бибилиотеки: pandas, nltk, pymorphy2, spacy и другие Работать с платформами для размещения сервиса онлайн. Например: Heroku Делать сайт, который по указанному имени канала выдаёт полезную аналитику. Код для парсера и аналитки можно посмотреть тут График динамики постов в телеграм канале Генерация фона музыкальных альбомов Датасет — нужно собрать самим, используя парсинг обложек, описание альбомов. Например можно использовать API Spotify. Задача — генерировать обложку музыкального альбома по жанру. Чему научитесь: Работа с GAN Работа с API Spotify, beautifulsoup, selenium для парсинга данных Бибилиотеки: pytorch/keras/tf, openCV и другие Работать с платформами для размещения сервиса онлайн. Например: Heroku Сравнение оригинальных обложок с сгенерированными Пейпер на эту тему — https://ryanmcconville.com/publications/AlbumCoverGenerationFromGenreTags.pdf Изучение загрязнения воздуха Датасет — нужно собрать самим или если воспользоваться открытыми. Например, данные с сайта https://airkaz.org/ с показаниями датчиков доступны Для получения более свежих данны обратитесь к создателю сайта. Задача — сделать полезный анализ данных, сделать модель, определить трэнд, сезонность , добавить внешние связынные данные. Например, погоду. Чему научитесь: Работа с временными рядами. Бибилиотеки: pandas, seaborn, folium, fbprophet и другие Сделать интерактивный сервис с ипользованием, например, Heroku и https://www.streamlit.io/ Карта г. Алматы с отметками датчиков и средним замером загрязнения воздуха Код доступен — https://github.com/alimbekovKZ/jupyter_notebooks_2/tree/master/airkaz Придумайте проект на любую тему. План действий может примерно такой: Найти данные. Данные могут быть или готовые из открытых источников или собраны из Интернета. Рекомендую собрать данные самим. Это разовьёт навыки парсинга и использование таких инструментов как selenium и beautifulsoup Сделать размкетку данных, если это необходимо Натренировать модели машинного обучения/ сделать автоматическую аналитику Реализовать сервис для работы модели машинного обучения. Рекомендую посмотреть в сторону — https://www.streamlit.io/ Разместить сервис на платформе, например: Heroku Дополнительно к прочтению, статья на тему pet-project — https://habr.com/ru/company/ods/blog/335998/ После реализации проекта будет, что показать потенциальному работодателю и можно будет вести предметный разговор о навыках и опыте который приобрели, делая проект. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Как освоить Data Science - личный опыт Обзор на онлайн-курсы для входа в профессию дата саентиста. Все курсы пройдены и описан субъективный взгляд и опыт. Классический ML Открытый курс OpenDataScience Открытый курс OpenDataScience https://mlcourse.ai/ Классный курс, сочетающий глубокую теорию и практические задания. Состоит из видео лекций на Youtube, статей на habr и заданий на github. Курс полностью о классическом машином обучении, поэтому нейронок тут не ждите. Рекомендую. Специализация Машинное обучение и анализ данных МФТИ и Yandex https://www.coursera.org/specializations/machine-learning-data-analysis (удален с coursera) Крутая специализация, крутые преподы. Курс плавно погружает в классическое машинное обучение. Специализация состоит из 6 курсов и позволяет как освоить теорию так и отработать навыки с Python. Больше всего понравились два курса из специализации: Математика и Python для анализа данных и Построение выводов по данным. Они круты тем, что темы изложенные в них в других курсах или встречаются редко или вообще их нет. Рекомендую. Data Mining in Action dmia Курс от авторов специализации МФТИ и Яндекса. Я его толком не проходил, но смотрел видео на Youtube. Рекомендую посмотреть, особенно по временным рядам. Курс «Машинное обучение» Воронцова https://www.youtube.com/playlist?list=PLJOzdkh8T5krxc4HsHbB8g8f0hu7973fK Видео по классическому машинному обучению. Будет СЛОЖНО и БОЛЬНО. Лучше посмотреть другие курсы с таким же содержанием и с большей концентрацией на практику. Не рекомендую. Специализация Advanced Machine Learning от ВШЭ https://www.coursera.org/specializations/aml Специализация состоит из 7 курсов. Я прошёл только 2 и они оставили два разных впечатления. Курс — How to Win a Data Science Competition: Learn from Top Kagglers, мне очень понравился. Пусть название вас не смущает, курс хоть и построен на соревнования с Kaggle даёт очень практические вещи. Например — работа с признаками, кодирование средними, EDA и поиск ликов в данных. Здорово расширяет набор навыков и взгляды на работу с данными. Крайне рекомендую. Курс — Natural Language Processing, у меня к нему сложилось нейтральное впечатление. Курс даёт NLP очень обширно и глубоко, но при выполнении заданий и тестов приходится много гуглить и читать. Курс показался сложным, а целью было именно вкатиться в NLP, но не забываем, что специализация называется Advanced Machine Learning. Рекомендую, при условии если уже есть базовые знания в NLP. DataCamp https://www.datacamp.com/ Единственная платная в обзоре платформа. Частые скдики позволяют купить за 99$ годовой доступ ко всем курсам. На платформе есть курсы по Python, R, SQL. На площадке есть career tracks, например Data Scientist with Python. Он состоит из 26 курсов — Python, визуализация, ml stack библиотеки Python, классический ML, немного Deep Learning. Главный плюс курсов на DataCamp, что можно быстро оттачить быстро навык написания просто и базового кода на Python. Отдельно рекомендую курсы Александра Дьяконова: Прикладные задачи анализа данных https://github.com/Dyakonov/PZAD Введение в машинное обучение https://github.com/Dyakonov/IML Машинное обучение и анализ данных https://github.com/Dyakonov/MLDM Deep Learning Back-propagation Deep Learning на пальцах https://dlcourse.ai/ Курс о deep learning с нуля, но на мой взгляд название не характеризует сам курс. Придется много гуглить для выполнения заданий, если вы совсем не знакомы c Python и Pytroch. В лекциях на Youtube очень хорошо рассказывается теория, но не уделено внимание практике. Рекомендую, если есть знания Python. Переходим на площадку coursera. Курс EE-559 — Deep Learning от École Polytechnique Fédérale de Lausanne, Switzerland. https://fleuret.org/ee559/ Курс с которого началось вдумчивое знакомство с Deep Learning и Pytorch. Он покрывает все сферы работы с нейронками: компьютерное зрение, NLP, GAN. Курс состоит из видео материалов, презентаций, конспектов и заданий на Pytorch. Материал очень гладко вводит в теорию машинного обучения, нейронок. На мой взгляд эта часть самая интересная и продуманная часть. Там много внимания уделено математике и выводу формул. Рекомендую. Deep Learning School кружок от ФПМИ МФТИ, рассчитанный на старшеклассников, интересующихся программированием и математикой, а также студентов, которые хотят начать заниматься глубоким обучением https://github.com/DLSchool/deep_learning_2018-19 Тут вас ждёт, просто масса материалов, жупитер тетрадок, записей семинаров и куча задачек для самостоятельного решения. Этот курс максимально подробен: математика, сверточные нейросети,U-Net,Object Detection, GAN. Дополнительно даны материалы по NLP, LSTM, Text2Speech, Speech2Text. Код примеров запускается к колабе. Максимально доступный материал для начинающих. Рекомендую. AI for Medical Diagnosis от команды Andrew Ng https://www.coursera.org/learn/ai-for-medical-diagnosis Чего не стоит ждать от курса: объяснения основ нейроннок, рассказа о том как лучше учить сети, к слову тут их учить не придётся. В одном задании будет код для обучения юнета, но запускать его не обязательно для выполнения задания. Код писать тоже особо не дадут, все упражнения представляют собой написание кода (Keras) в уже готовый жупитер ноутбук в отмеченное место. Многие вещи, как например GradCam вообще не объясняют, а дают просто запустить и посмотреть результат. Из плюсов — хорошая секция про оценку моделей. Хорошая, потому что там дают код, который можно переиспользовать у себя. Самому лень было писать такое. Так же из плюсов отмечу, что если вы уже проходили курсы или умеете в нейронные сети, то AI for Medical Diagnosis станет неплохим дополнением. При условии, что тема медицины для вас интересна. Не рекомендую. Отдельно рекомендую курс Александра Дьяконова: Глубокое обучение https://github.com/Dyakonov/DL Какие еще курсы пройти пока вкатываешься в DS/ML Гистограммы частот и графики box-plot Погружение в Python от МФТИ и Mail.Ru Group & ФРОО https://www.coursera.org/learn/diving-in-python/ (удален с coursera) Отличный курс по Python. Этот курс расширит арсенал и научит писать многопоточные и параллельные приложения. Отлично объяснит ООП, магические методы и дескрипторы. Задания тоже очень крутые, например: предстоит написать клиент и сервер для отправки метрик. Рекомендую. Платформа stepik https://stepik.org/ На этой платформе я прошел несколько курсов и могу смело рекомендовать следующие: Основы статистики часть 1, 2, 3 от Bioinformatics Institute https://stepik.org/course/76/syllabus Этот курс помог мне освежить в памяти статистику. Очень крутые леции и лекторв, доступным языком объяснены сложные вещи. Три курса охватывают области, которые вам будут необходимы в работе. Неудобство вызывает R в части 2 и 3, но задания не сложные, можно решить гуглением и без того, что бы вникать в R. Курсы по алгоритмам: Алгоритмы: теория и практика. Структуры данных https://stepik.org/course/1547 и Алгоритмы: теория и практика. Методы https://stepik.org/course/217 Полезные курсы, даёт полное представление о базовых структурах данных и алгоритмах. Задачки можно выполнять на трёх языках — C++, Python, Java. Еще из плюсов это объяснение решений после выполнения задачек. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Чеклист для запуска Machine Learning  проекта В этой заметке постараюсь раскрыть мысли по поводу необходимых шагов для старта проекта в области Machine Learning. Необходимые данные Набор данных для обучения Исторические данные — для обучения предсказательных моделей Обучающая выборка — образцы того, что мы хотим найти/предсказать — для обучения модели Достаточной глубины (с учетом сезонности и т. п. до нескольких лет) Достаточного объема, репрезентативная выборка Набор данных для тестирования Исторические данные — для тестирования предсказательных моделей Тестовая выборка — для проверки качества модели Достаточного объема, репрезентативная выборка Актуальные данные — материал для работы модели Источники данных «Сырые» данные — логи разного рода, фотографии, аудиозаписи Структурированные данные — корпоративные системы, комплексные хранилища данных (КХД), системы управления контентом (ECM) в том числе метаданные Внешние данные Открытые источники (соцсети , интернет) Приобретаемые данные Проблема с которой вы можете столкнуться, это чувствительность данных. Решается следующими методами: Деперсонализация — замена персональных идентификаторов на условные (хэширование, кодирование и т. п.) Снижает категорию персональных данных Облегчает обмен данными со сторонними организациями Не решает проблему полностью Обфускация — искажение данных таким образом, чтобы снизить чувствительность, но сохранить полезность Существенно снижает риски утечки или злоупотребления Требует предварительного согласования в зависимости от использования данных Теперь перейдем непосредственно к старту проекта. Для начала необходима стратегия работы, которую нужно определить заранее. Обеспечение наличия и доступности данных для произвольных задач Сбор собственных данных Сбор открытых данных Приобретение чужих данных Экспериментальный подход к бизнесу (A/B тестирования и эксперименты как таковые) Использование своих и внешних ресурсов и инструментов Обеспечение сбора и доступности данных — собственные данные Постулирование ценности данных, независимо от возможности их немедленного использования Переоценка полезности данных с учетом применения технологий BD/ML Структрированные транзакционные Неструктурированные Логи и т. п. Инвентаризация потоков данных, с учетом переоценки, пересмотр подхода к хранению данных Форматы Сроки Обеспечение сбора и доступности данных — внешние данные Поиск внешних источников и поставщиков данных Создание и развитие механизмов сбора и «интеграции» внешних и внутренних данных Последовательная работа по оценке полезности внешних данных, включению их в повседневную деятельность Экспериментальный подход к бизнесу Постепенный переход от субъективных экспертных оценок к объективным экспериментальным Формирование культуры эксперимента Постоянное проведение экспериментов Значительное внимание к дизайну экспериментов Требование измеримых результатов Необходимо помнить, что проекты в области Machine Learning, обладают рядом особенностей: Внимание на данные, а не на функции. Функционально решение крайне бедное, в общем случае реализуется одна функция Ограниченная применимость отработанных подходов внедрения, ориентированных на функции Вместо функционального ТЗ — требования к качеству модели Вместо опытной эксплуатации — эксперимент Во время промышленной эксплуатации необходима постоянная оценка и подстройка модели Теперь переходим к самой главной части статьи. Жизненный цикл проекта в области Machine Learning: Определение целей, ограничений, критериев успеха — инициирование Определение требований к данным, доступности данных, получение образцов данных Определение формата результатов и способов использования результатов, детальное описание эксперимента, фиксация рамок проекта Передача и прием данных, препроцессинг, мэтчинг Построение, обучение, тестирование модели Экспериментальная проверка модели, опытная эксплуатация Интеграция модели в ИТ-инфраструктуру Эксплуатация решения, завершение проекта, промышленная эксплуатация и поддержка Этап первый — Инициирование проекта Определение цели и критериев успеха в терминах бизнеса Оценка доступности данных Оценка реалистичности задачи Определение возможности и формы экспериментальной проверки Предварительное планирование Этап второй- Определение требований к данным Инвентаризация доступных данных Номенклатура Образцы Объем Глубина Наличие обучающей выборки (при необходимости) Оценка достаточности данных и возможности получения дополнительных данных. Определение чувствительности данных, возможности и формы их передачи, методов защиты и снижения чувствительности данных. Этап третий- Определение формата результатов, фиксация рамок проектам Определение формата и способа использования результатов проекта Данные — выгрузка / загрузка Сервис по обработке данных Результаты анализа данных Модель как таковая (вместе со средой исполнения или отдельно) Детальное описание эксперимента Планирование проекта Фиксация рамок проекта, включающих все аспекты проекта Этап четвертый- Передача и прием данных, препроцессинг, мэтчинг Определение способа передачи данных По каналам связи На носителях Препроцессинг Обфускация Деперсонализация Прием данных Оценка соответствия соглашениям Проверка полноты При необходимости мэтчинг данных из разных источников Чем меньше обработаны и обфусцированы данные, тем проще мэтчинг Определение технологий мэтчинга Этап пятый- Построение, обучение, тестирование модели С точки зрения управления этот этап «черный ящик». Что видно снаружи: Успешность приема данных, согласие с их достаточностью Определенность внутренних метрик качества Появление первой версии модели измеримого качества Повышение качества модели от версии к версии Соблюдение графика / отставание от графика Этап шестой- Экспериментальная проверка модели Практическая реализация эксперимента Сбор данных в ходе эксперимента Расчет итогов Оценка результатов Решение о продолжении проекта / запуске сервиса Этап седьмой- Интеграция модели в ИТ инфраструктуру Выбор способа интеграции Определение места размещения runtime части модели Этап восьмой- Эксплуатация и поддержка модели Определение Service Level Agreement (SLA) Вот и все. Надеюсь эта информация поможет вам при запуске проектов в области Machine Learning. Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе. ### Machine learning and data science learning CoursesHow To Learn a Data Science – my experienceMedical Image Analysis In PythonPractical tasks of analytics and machine learningRFM analysis in PythonCohort Analysis in PythonCalculating Monthly Recurring Revenue (MRR) in PythonLLMDeep dive into LLM Part OneDeep dive into LLM Part TwoMachine Learning and Data Science for beginnersPandas for Data Science ### Machine learning system design ML pipelineMachine learning pipeline-basics. Cookiecutter and HydraCode and model versioningMicroservices, REST APIFlask and REST APIBentoML – Faster Machine Learning PrototypeModel deployment with Google Cloud FunctionsCI/CDFeature Store - data management for machine learningDocker for MLSpeed-up & ScalabaleData quality and monitoring of models in productionEvidently and custom metrics ### Изучение Machine Learning и Data Science КурсыКак освоить Data Science — личный опытБесплатный мини курс — анализ медицинских изображений в PythonПрактические задачи аналитики и машинного обученияRFM анализ в PythonКогортный анализ в PythonРасчет Monthly Recurring Revenue (MRR) в PythonLLMПогружение в LLM часть перваяПогружение в LLM часть втораяData Sciеnce и Machine Learning для начинающихPandas для Data Science ### Внедрение моделей машинного обучения в промышленную эксплуатацию ML pipelineMachine learning pipeline — основы. Cookiecutter и HydraВерсионность кода и моделейМикросервисы, REST APIРазрабатываем API на FlaskBentoML — быстрый Machine Learning прототипДеплой модели с Google Cloud FunctionsCI/CDFeature Store – управление данными для машинного обученияDocker для MLSpeed-up & ScalabaleData Quality и мониторинг моделей в продеEvidently и кастомные метрики ### About the author / Contacts My name is Renat. I live and work in the city of Almaty, Republic of Kazakhstan. I’m currently working as a Deep Learning Scientist/ Machine Learning Engineer. I mainly work with faces and medical images. In addition, I am currently working as a mentor at Yandex.Practicum. I help students to master the profession of Data Analyst and Data Scientist. For a long time I worked in banks. I was a lead in internal audit, introduced DS / ML approaches there. Then I worked as a team lead in scoring and credit analysis. In this blog I write tutorials and practical tips on DS and ML, talk about the career, application and training of Data Science. My interests and goals: MedTech, AdTech, EduTech. You can contact me through: My email Twitter Github LinkedIn Projects I design and develop a service with a machine learning component I blogging in Telegram channel about the career, application and training of Data Science (Russian Language in general) I participate in competitions on the kaggle: profile Kazakhstan data science/machine learning community Moderate 2500+ member strong Telegram chat with a learning resources archive and a job board (1500+ members) Organized a community for online co-op courses Writing articles for NewTechAudit Podcasts with me Code and coffee # 8. Who and how is using Deep Learning to diagnose COVID-19 in Kazakhstan? (Russian) https://www.youtube.com/watch?v=0x7Vnwv1N5A&list=PL3q8gXVayhpf-Sy2ACFUhelV6KODL7IVa&index=9 Artificial intelligence helps Kazakh doctors diagnose coronavirus ### Sitemap 202516 мая Retrieval-Augmented Generation (RAG): Recent Research and Challenges16 мая Retrieval-Augmented Generation (RAG): Последние Исследования и Вызовы202429 ноября How to Speed Up LLMs and Reduce Costs: Edge Models29 ноября Как ускорить LLM и снизить затраты. Edge модели22 октября Курс Управление AI и ML продуктами1 октября Trending Articles on Large Language Models1 октября Трендовые статьи по Large Language Model26 сентября All the Latest in the World of LLM26 сентября Все новое из мира Large Language Model23 сентября Key Trends in LLM Reasoning Development23 сентября Основные тенденции в развитии рассуждений LLM15 августа Pandas for Data Science15 августа Pandas для Data Science3 июля Поиск удаленной работы в 2024 году13 апреля Deep dive into LLM Part Two13 апреля Погружение в LLM часть вторая26 марта Deep dive into LLM Part One26 марта Погружение в LLM часть первая10 января Какие фреймворки должен знать продакт-менеджер202316 ноября Machine learning pipeline-basics. Cookiecutter and Hydra16 ноября Machine learning pipeline — основы. Cookiecutter и Hydra27 октября Evidently and custom metrics27 октября Evidently и кастомные метрики15 сентября Налоговый календарь для ИП в Казахстане7 августа Стань экспертом в Machine Learning и MLOps14 июля Skills for different Data scientists levels14 июля Компетенции для разных уровней Data Scientists12 апреля How to Become a Machine Learning Engineer12 апреля Как стать Machine Learning Engineer3 марта Конспект книги «Правила магической пирамиды для делового письма»3 марта Конспект книги «Кратко. Ясно. Просто»202222 декабря Model deployment with Google Cloud Functions22 декабря Деплой модели с Google Cloud Functions23 ноября Calculating Monthly Recurring Revenue (MRR) in Python23 ноября Cohort Analysis in Python23 ноября RFM analysis in Python14 марта Способы регистрации обращений клиентов202121 декабря Как подготовиться к Data Science интервью13 октября Medical Image Analysis In Python6 сентября Simple steps to make your Python code better6 сентября Простые шаги сделать ваш Python код лучше9 августа How to prepare for a data science interview8 июня BentoML — Faster Machine Learning Prototype8 июня BentoML — быстрый Machine Learning прототип31 марта Курс — анализ медицинских изображений в Python4 марта Расчет Monthly Recurring Revenue (MRR) в Python26 февраля Когортный анализ в Python18 февраля RFM анализ в Python5 февраля Python logging HOWTO: logging vs loguru5 февраля Выбираем логирование в Python: logging vs loguru26 января Machine Learning Models in production: Flask and REST API19 января How to make your CV attractive with a pet project13 января How To Learn a Data Science — my experience10 января Machine learning в продакшн — Flask REST API10 января Как сделать резюме привлекательным с помощью pet project10 января Как освоить Data Science — личный опыт10 января Чеклист для запуска Machine Learning  проекта ### Об авторе/ Контакты Меня зовут Ренат. Я живу и работаю в городе Алматы Республика Казахстан. Я работаю в на позиции Deep Learning Scientist/Machine Learning Engineer. В основном работаю с лицами и медицинскими изображениями. Кроме того сейчас я работаю наставником в Яндекс.Практикуме. Помогаю студентам освоить профессию Data Analyst и Data Scientist. Долгое время я работал в банках. Был руководителем во внутреннем аудите, внедрял там подходы DS/ML. Затем работал тим лидом в скоринге и кредитном анализе. В этом блоге я пишу обучалки и практические советы по DS и ML, расскажу про карьеру, применение и обучение Data Science. Мои интересы и цели: MedTech, AdTech, EduTech. Со мной можно связаться через: Мой email Twitter Github LinkedIn Проекты Проектирую и разрабатываю сервис с machine learning составляющей Веду Telegram канал про карьеру, применение и обучение Data Science. Участвую в соревнованиях на площадке kaggle: профиль Казахстанское сообщество data science/machine learning Организовал сообщество совместного прохождения курсов Модерация чата Telegram с 2500+ участниками с архивом учебных ресурсов и доской по вакансиям (1500+ участников) Пишу статьи для NewTechAudit Подкасты со мной Код и кофе №8. Кто и как применяет Deep Learning для диагностики COVID-19 в Казахстане? https://www.youtube.com/watch?v=0x7Vnwv1N5A&list=PL3q8gXVayhpf-Sy2ACFUhelV6KODL7IVa&index=9 Искусственный интеллект помогает казахстанским врачам диагностировать коронавирус ### Карта 202516 мая Retrieval-Augmented Generation (RAG): Recent Research and Challenges16 мая Retrieval-Augmented Generation (RAG): Последние Исследования и Вызовы202429 ноября How to Speed Up LLMs and Reduce Costs: Edge Models29 ноября Как ускорить LLM и снизить затраты. Edge модели22 октября Курс Управление AI и ML продуктами1 октября Trending Articles on Large Language Models1 октября Трендовые статьи по Large Language Model26 сентября All the Latest in the World of LLM26 сентября Все новое из мира Large Language Model23 сентября Key Trends in LLM Reasoning Development23 сентября Основные тенденции в развитии рассуждений LLM15 августа Pandas for Data Science15 августа Pandas для Data Science3 июля Поиск удаленной работы в 2024 году13 апреля Deep dive into LLM Part Two13 апреля Погружение в LLM часть вторая26 марта Deep dive into LLM Part One26 марта Погружение в LLM часть первая10 января Какие фреймворки должен знать продакт-менеджер202316 ноября Machine learning pipeline-basics. Cookiecutter and Hydra16 ноября Machine learning pipeline — основы. Cookiecutter и Hydra27 октября Evidently and custom metrics27 октября Evidently и кастомные метрики15 сентября Налоговый календарь для ИП в Казахстане7 августа Стань экспертом в Machine Learning и MLOps14 июля Skills for different Data scientists levels14 июля Компетенции для разных уровней Data Scientists12 апреля How to Become a Machine Learning Engineer12 апреля Как стать Machine Learning Engineer3 марта Конспект книги «Правила магической пирамиды для делового письма»3 марта Конспект книги «Кратко. Ясно. Просто»202222 декабря Model deployment with Google Cloud Functions22 декабря Деплой модели с Google Cloud Functions23 ноября Calculating Monthly Recurring Revenue (MRR) in Python23 ноября Cohort Analysis in Python23 ноября RFM analysis in Python14 марта Способы регистрации обращений клиентов202121 декабря Как подготовиться к Data Science интервью13 октября Medical Image Analysis In Python6 сентября Simple steps to make your Python code better6 сентября Простые шаги сделать ваш Python код лучше9 августа How to prepare for a data science interview8 июня BentoML — Faster Machine Learning Prototype8 июня BentoML — быстрый Machine Learning прототип31 марта Курс — анализ медицинских изображений в Python4 марта Расчет Monthly Recurring Revenue (MRR) в Python26 февраля Когортный анализ в Python18 февраля RFM анализ в Python5 февраля Python logging HOWTO: logging vs loguru5 февраля Выбираем логирование в Python: logging vs loguru26 января Machine Learning Models in production: Flask and REST API19 января How to make your CV attractive with a pet project13 января How To Learn a Data Science — my experience10 января Machine learning в продакшн — Flask REST API10 января Как сделать резюме привлекательным с помощью pet project10 января Как освоить Data Science — личный опыт10 января Чеклист для запуска Machine Learning  проекта